Create .zip Files from Code

If you've ever wanted to create a .zip file from your application, the System.IO.Compression.GZipStream will let you do it, assuming that you're comfortable with your file being in the industry-standard .gzip format (though I'm told you can swap in other compression schemes).

For this tip, I'm assuming that the file is small enough that you can read it all in one gulp. In that scenario, my first move is to define a FileStream object for the file I want to compress, read the file into memory, and close the FileStream:

Dim unCompressedFile As FileStream
unCompressedFile = File.OpenRead("C:\GreatBigFile.txt")
Dim bytes(5000) As Byte
Dim bytesRead As Integer
bytesRead = unCompressedFile.Read(bytes, 0, 5000)
unCompressedFile.Close()

My next move is to create a FileStream object for the compressed file I want to create:

Dim CompressedFile As FileStream
CompressedFile = File.Create("C:\IttyBittyFile.gzip")

With all the files in place, I'm ready to create the GZipStream object that will do the actual compression. You have to pass two parameters when creating the GZipStream object: The first is the FileStream for the compressed file you intend to create; the second indicates that you want to compress the file.

Here's my code to create a compressed file called IttyBittyFile.gzip:

Dim zipper As GZipStream
zipper = New GZipStream(CompressedFile, CompressionMode.Compress)

Now I can use the GZipStream Write method to write out the compressed file, passing the bytes I retrieved from the original file:

zipper.Write(bytes, 0, bytesRead)

Finally, of course, I close the GZipStream object and my compressed file:

zipper.Close()
CompressedFile.Close()

As you probably suspect, if you change the CompressionMode and pass in a compressed file, you can use GZipStream to decompress a file.

Posted by Peter Vogel on 12/10/2015 at 9:46 AM0 comments


Creating a NuGet Web Site

In my regular Practical.NET column, I showed how easy it is to create NuGet packages and discussed how it was a much better way for a developer to share anything you've created, from Entity Framework classes to JavaScript files (my example was a package that implemented an HtmlHelper consisting of a DLL and a JavaScript file). NuGet also allows you to attach searchable documentation to your package to ensure that a developer can find your package, recognize it and know what your code does.

In that article, I showed how to use a folder as a repository for NuGet packages. But if you'd like something a little more professional, you can create a NuGet Web site. It's easy to do: First, in Visual Studio, create an Empty Web Application. Once the project appears in Solution Explorer, right-click on it and select Manage NuGet Packages. In the NuGet Package Manager, do a search for the NuGet.Server package and install it.

After deploying your Website, you just need to do two things:

  1. Save your NuGet packages into the Packages folder in your new site.
  2. Tell Visual Studio about your site.

My earlier article walks through both processes. You can get the information for your site by surfing to it with your browser -- its default page provides both the file path to the folder you should save your package in and the URL you should use when telling Visual Studio about your NuGet site.

I'll put in one caveat: I only tested this on IIS 7.

Posted by Peter Vogel on 12/03/2015 at 10:18 AM0 comments


Stop Being Bugged About Changed Files

Every once in a while, you have a file open in one of your Visual Studio tabs and the file is updated on the disk. Unlike when any unopened files/folders in Solution Explorer are changed, Visual Studio notices this change. The result is that you get a dialog telling you that the “file has been modified outside of the editor” and are asked if you “want to reload it?” There are, essentially, two buttons on the dialog: Yes and No.

I have never clicked No. Not once. Not ever.

So, the other day, I took the plunge and turned off this dialog: I shouldn’t ever see that message again. Instead, my changed file will be quietly refreshed. If you also want to get rid of the dialog, first go to the Tools menu and select Options. From the Environment treeview on the left side of the resulting dialog, drill down to the Documents node and, on the right, check the option under “Detect when file is changed.” This will cause Visual Studio to skip the dialog and just reload the changed version of the file.

Depending on which version of Visual Studio you have, that option will be called “Autoload Changes, If Saved” or the more obvious “Reload modified files unless there are unsaved changes.” Either way, as long as you haven’t made changes to the file, the changed file will automatically (and silently) be refreshed in the editor tab. If you’ve made changes to the file and haven’t saved them yet, you’ll get a dialog asking if you want to keep your changes.

Quite frankly, I don’t know why it isn’t the default.

Posted by Peter Vogel on 11/17/2015 at 9:43 AM0 comments


Protecting Shared Fields in Asynchronous Processing

Sometimes, in a C# application with multiple threads running simultaneously, you need to share data. So you set up a variable declared outside of any method or property (a "field") and have the different threads share data by updating and reading that variable. It should work ... but it doesn't and you can't figure out why.

The odds are that there's some bug in your asynchronous code that's creating the problem. However (and this is a long shot), it might be the compiler's fault. Some of the optimizations the compiler applies to a field assume that the field will only be accessed by a single thread at a time. This means your source code might look fine ... but the optimized code you're executing is doing something different.

There are two solutions in C#: First, put a lock around any code that accesses the field (this option is also available in Visual Basic). You might take a hit on performance as threads queue up to get to your field, but it ensures that you both keep the compiler's optimizations and have only one thread accessing the field at a time.

If you don't think you can find all the places that the field is being read or written (or are too lazy to look) you can, in C#, mark the variable as volatile:

internal volatile string Status;

The volatile keyword causes the compiler to omit the optimizations that assume single-thread access. You'll still take a performance hit because, internally, the compiler will cause reads and writes to your variable to be processed in sequence. But, now, when your application still doesn't work, you'll know it's your fault.

Visual Basic doesn't have an equivalent to the volatile keyword. However, if you can track down all the places where you read or write the field, you can use the Thread object's VolatileRead and VolatileWrite methods when working with the field.

Posted by Peter Vogel on 11/04/2015 at 10:07 PM0 comments


Properties with Parameters (and Making Them the Default)

Most developers aren't aware that you can write properties that accept parameters, just like a method does. Of course, it isn't often that you need a property that accepts a parameter. One way I recognize that I could use a property rather than a method is when my method name begins with the word "Get." Here, for example, is a method that (I assume) returns the specified part of a name:

Public Class NameManager
  Public Function GetNamePart(NamePosition As Integer) As String
    '...code
  End Function

If I rewrite the method as a property (and rename it), my class code looks like this:

Public Class NameManager
  Public ReadOnly Property NamePart(NamePosition As Integer) As String
    Get
      '...code
    End Get
  End Property

A developer who wants to get the customer's middle name would write code like this:

Dim nm As New NameManager("Peter Hunter Vogel")
Dim middleName As String
middleName = nm.NamePart(2)

You can go one step further and make this property the default property for the class, in which case a developer doesn't even have to use the property name. Here's the relevant code in Visual Basic (which adds the modifier Default to the property's signature):

Public Class NameManager
  Default Public ReadOnly Property NamePart(NamePosition As Integer) As String
    Get
      '...code
    End Get
  End Property

Here it is in C# (which renames the property to the keyword "this"):

public class NameManager
  public string this(int NamePosition) 
    get {
      '...code
   }

Regardless of how the class is written, the code to retrieve the middle name now looks like this:

middleName = nm(2)

Posted by Peter Vogel on 10/29/2015 at 3:12 PM0 comments


Why Won't My Razor Code Compile!?!

I've said it before: The Razor code that I enter into my ASP.NET MVC Views looks like magic to me. The ability Razor gives me to mix HTML and code surpasses my understanding. But, like magic, because I don't understand why Razor works, there are times where I don't understand why Razor doesn't work.

And neither do my clients, one of whom called me up last week to ask why code like the following wasn't acceptable to Razor (in C#, equivalent code wouldn't require the second @ ... but it still wouldn't compile):

@If RowRequired Then
  @<tr>
End If

The problem is that, inside a code block (like this If…Then block), Razor requires that all open tags have a matching close tag. Razor is fine with this code, for example:

@If RowRequired Then
  @<tr></tr>
End If

This can make structuring your HTML a little more awkward but, there is a solution: use @: instead of plain old @. With @:, this code compiles:

@If RowRequired Then
  @:<tr>
End If
</tr>

That's sharp!

Posted by Peter Vogel on 10/23/2015 at 1:16 PM0 comments


Catching Every Keystroke with jQuery

In an earlier column I used the jQuery change function to wire up a function to run after a user makes a change to an entry in a textbox. That "after" is important because the function I wired up won't run when the user makes a change in a textbox -- the event waits until the user leaves the textbox before firing.

In that article I mentioned, in passing, that if you really did want to catch a change as soon as a user makes it, you want to wire up the oninput event: The oninput event really does fire as soon as the user makes any change in a textbox. The major issue with oninput is that it's only available in browsers that support that portion of the HTML5 specification.

Unlike many other HTML events there's no built-in jQuery function to pick up the oninput event, so you need to use the jQuery on function to wire up a function to the event.

Here's some code that wires up a function that displays an alert box as soon as the user makes a change:

$(":text").on("input", function () { alert("got it"); });

You'll notice in my code that I'm using the :text selector, which only wires my function up to textboxes (it doesn't attach other input elements like passwords or checkboxes and also ignores dropdown lists and textareas). Several of the elements I'm skipping don't need the oninput event because the jQuery change event fires as soon as the user makes a change: Checkboxes and dropdown lists fall into that group. Password textboxes and textareas don't get caught by the :text selector, however, so you'll need to use more selectors to catch events immediately with them.

Posted by Peter Vogel on 10/13/2015 at 10:43 AM0 comments


Returning Server-Side Errors from AJAX Calls

In ASP.NET MVC if you call an action method on the server from JavaScript code and that action method raises an exception, you'll get an error at the client that lets you know something has gone wrong. Unfortunately, all the information you typically get is the HTTP 500 error status code and it's default message.

If you want to get your own custom error message delivered to the client, you could create your own custom error object and return it from the server when something goes wrong. Unfortunately, with that solution jQuery won't call the error function you specified in your $.ajax call -- you'll have to write your own code to check if the object returned from the server is your error object .

A better solution is to instantiate and return your own HttpStatusCodeResult, which does cause jQuery to call the error function you specify in your $.ajax call. This server-side code will do the trick, while providing a custom message to go down to the client:

return new HttpStatusCodeResult(410, "Unable to find customer.")

On the client, your message will be in the third parameter passed to your error function.

If you're handling multiple error conditions in the same action method and need to take different actions at the client depending on the error, you can give each error a different status code. If so, in your client code you'll need to check the error status code to see what error has triggered your error function. The error code is returned in the status property of the first parameter passed to your error method.

This client-side example calls a server-side method and, if the method returns a 410 error, displays my custom error message to the user:

$.ajax({url:'/home/deleteCustomer',
  data: {id: "A123"),
  success: function (result) {//handle successful execution},
  error: function (xhr, httpStatusMessage, customErrorMessage) {
    if (xhr.status === 410) {
      alert(customErrorMessage);}}});

Here's the list of defined HTTP status codes. If your message is suggesting that the error is something that the user can fix, then you should probably pick a code from the 400 series (that series is reserved for client errors). Personally, I don't think developers are using status code 418 ("I'm a teapot") enough.

Posted by Peter Vogel on 10/07/2015 at 11:28 AM0 comments


Display Just One Project in Solution Explorer

In a solution with many projects, typically you just want to work with one of the projects. You can, of course, collapse all of the projects you're not interested in, but (depending on how many projects you have) that can still leave a lot of lot clutter in Solution Explorer … and the project you're interested in half-way down the list. And the reality is that, from time to time, you're going to have to expand those other projects, which puts all that clutter back into Solution Explorer.

If, however, you right-click on the project you're mostly interested in and select Scope to This, Solution Explorer will switch Solution Explorer to a view that shows your project and nothing else. Now, when you need to get back to the full solutions listing, you just have to click the back button at the top of Solution Explorer. Back in the full version of Solution Explorer, you can return to your scoped, single project view by clicking the forward button right beside the back button.

This is a simpler solution than my previous tip on opening a separate Solution Explorer for individual projects. To begin, using Scope to This, you can only have a single project in a window by itself -- if you scope to another project you lose the scope on any other project. But, while opening multiple Solution explorers is more flexible I bet that, most of the time, scoping to one project is all the solution you need.

Posted by Peter Vogel on 09/29/2015 at 11:19 AM0 comments


Creating Your Own ASP.NET MVC Authorization Attribute

Applying role-based security is easy in ASP.NET MVC: Just decorate the relevant action method/controller class with the Authorization attribute, specify the allowed roles, and you're done. Every once in a while, though, I have a case where role-based security isn't enough.

For example, a client needed security to be applied differently depending on whether the current user was in the eastern or western division of the company. We could've duplicated all the roles in the company (EasternManager vs. WesternManager) or tried to find some clever way to combine roles (for example, assign users to an Eastern or Western role in addition to assigning them to the Manager role) and stack authorization attributes on each method. In the end I decided it was just as easy to create my own division-based Authorization attribute.

To create your own Authorization attribute you just need to create a class that inherits from AuthorizeAttribute and override its AuthorizeCore method. Your AuthorizeCore method must return True or False depending on whether you decide the user is accepted or rejected. This example rejects everyone:

Public Class DivisionAuthorization
  Inherits AuthorizeAttribute

  Protected Overrides Function AuthorizeCore(httpContext As HttpContextBase) As Boolean
    Return False
  End Function

End Class

If you want to send the user to a custom page of your own (rather than sending the Web server's default 404 page) you can also override the HandleUnauthorizeRequest method and use a redirect method inside the method to specify the controller/action method name that displays your rejection page.

One hint and one caveat before I'm done:

The hint: You can get ASP.NET MVC's opinion on whether the current user is authorized by calling the base AuthorizeCore method, and passing the same parameter that's passed to your AuthorizeCore method.

The caveat: Your AuthorizeCore method must be thread-safe, so you should only use local variables inside of it.

Posted by Peter Vogel on 09/24/2015 at 10:37 AM0 comments


Multiple Solution Explorers

If you've right-clicked on a project in Solution Explorer, you've probably noticed (but haven't used) the New Solution Explorer View choice. Clicking on that choice with a project selected in Solution Explorer opens a new Solution Explorer view that displays just that project. Initially, the new, dedicated view is free-floating but you can dock it anywhere you want, including docking it as a tab beside your "full" Solution Explorer view.

This is a great alternative to scrolling up and down between two projects in a solution: Once you've opened a view dedicated to a project and docked it, you can just click on the tab that displays the project with which you want to work.

There are two disappointments: You can't name the tab (so you end up with multiple tabs called "Solution Explorer"); Visual Studio doesn't remember your dedicated views from one editing session to another (it also drops any dedicated views if, for example, you add a new project to the solution).

You can actually open a new Solution Explorer view dedicated to almost any item in Solution Explorer, but I've only ever found it useful for projects.

Posted by Peter Vogel on 09/21/2015 at 10:56 AM0 comments


Convincing Razor to Recognize All of Your Expression

Razor's ability to distinguish between code and HTML/text often looks like magic to me. However, like any good magic act, I'm sometimes surprised by the results I get. For example, this code in a View didn't give me the results I expected:

@SalesOrder.CustomerName & " -- unknown"

Instead of getting the customer's name followed by " -- unknown", I got this:

Peter Vogel & " -- unknown"

Razor had decided that my expression ended at the space before my ampersand. Fortunately, to tell Razor where the real end of my expression is, I just have to include the whole expression in parentheses. This code solved my problem:

@(SalesOrder.CustomerName & " -- unknown")

Now I get:

	Peter Vogel – unknown

which is precisely what I want.

Posted by Peter Vogel on 09/14/2015 at 10:10 AM0 comments


Upcoming Events

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.