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/20150 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/20150 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/20150 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/20150 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/20150 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/20150 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/20150 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/20150 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/20150 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/20150 comments


Integrate Action Methods into ASP.NET MVC Partial Views

I find it handy to assemble complex Views from multiple simpler Partial Views. Sometimes, however, the result is a lot of code in my Views (I even did a column about managing that code). But there's another solution: The HtmlHelper's Action helper method, which allows you to call an action method and incorporate the results of that action method into your View.

This code in a View, for example, calls an action method named DisplayCustomer and adds the Partial View returned by DisplayCustomer to the View:

@Html.Action("DisplayCustomer")

My example is just the simplest way to call your action method -- you can also pass a controller name and an anonymous object with various property values.

Using the Action method lets you put much of your View-related logic where it belongs: in a method in your controller and not in your View (in the MVC design pattern, Views should have no logic at all). And, of course, once your logic is in a controller method, you can test it.

You probably don't want anyone invoking one of these action methods directly. You can tell ASP.NET MVC not to let that happen by decorating your action method with the ChildActionOnly attribute, like this:

<ChildActionOnly>
Function DisplayCustomer() As ActionResult
  Return PartialView("CustomerData")
End Function

Posted by Peter Vogel on 09/04/20150 comments


The Answer to Every File Path Related Problem

If you do anything at all with file path, you need the Path class (in the System.IO namespace). The methods on the Path class that you're most likely to use include:

  • GetTempFileName: Doesn't just return a filename that's guaranteed to be unique -- it also creates the file in the TEMP folder so you can start writing to it
  • GetFileName: Returns the file name from a path (and returns null if the path is just the path to a folder without a file name)
  • GetDirectoryName: Passed a file path, pulls out the full path to the folder without the closing backslash. One warning: this method returns null if passed the root folder ("c:\")
  • Combine: Puts a set of strings together to create a valid file path. Combine will add or remove backslashes as necessary, so the method will do the right thing with the path return by GetDirectoryName

These are the answers; any more questions?

Posted by Peter Vogel on 08/24/20150 comments


Subscribe on YouTube