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


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/2015 at 10:34 AM0 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/2015 at 10:18 AM0 comments


Finding Matching Brackets in C#

You can tell that the Visual Studio team recognizes the primary issue C# developers face: finding the matching bracket. That must be true because the most obvious way of finding "the other bracket" is built into the way code is displayed: When you put your cursor beside one bracket (open or close), both it and the matching bracket are highlighted (or, because the default color for the brackets is gray: lowlighted).

Unfortunately, that isn't much help if the "matching" bracket is off the screen: you can't see the highlighting if the bracket isn't visible. In those situations my fallback method used to be the plus/minus signs in the left hand margin of the editor window: I collapsed my C# methods to see what code disappeared and what code remained visible. The problem here, of course, is that the collapsed code was often the code in which I was interested.

There's a third option that not a lot of developers know about: Place your cursor on the bracket you're trying to match (open or close) and press Ctrl+] (that's the Control key with a closing square bracket). Your cursor moves to the matching bracket. Pressing the key combination again takes you back to the bracket on which you started.

There are other benefits: If you're bored and stuck on a problem, I've found repeatedly pressing Ctrl+] and watching the cursor snap back and forth can be soothing. And, if anyone is watching, it looks like you're working.

Posted by Peter Vogel on 08/19/2015 at 9:57 AM0 comments


Comparing Strings Without Worrying About Case

Developers frequently want to ensure two strings are identical without having to worry if some characters are in uppercase in one string and the same characters are in lowercase in the other string. Frequently, you see developers using either ToUpper or ToLower to avoid the problem:

If Name.ToUpper = OtherName.ToUpper Then...

But both ToUpper and ToLower create new strings, which is extra (and unnecessary) work.

If you can live with some extra typing, you can avoid generating those new strings by using the Equals method that every variable has, passing the InvariantCultureIgnoreCase choice from the StringComparison enumeration:

if (Name.Equals(OtherName, StringComparison.InvariantCultureIgnoreCase))

Now you have much less to worry about.

Posted by Peter Vogel on 08/12/2015 at 10:20 AM0 comments


Checking If You Can Use a Class in C#

The is keyword lets you check if a variable is pointing to an object of a particular class (or a class that inherits from some class). For example, the code in this if block only executes if CustomerVariable is pointing at an object of type Customer (or some class that inherits from Customer):

if (CustomerVariable is Customer)
{
  ...code to execute...
}

It works with interfaces, too:
if (CustomerVariable is ICustomer)
{
  ...code to execute ...
}

You can do your test and get a free cast from a variable by using the as keyword. If the cast fails, no exception is raised, but your destination variable is set to null, telling you that the variable isn't compatible with the object. The following code not only does what the previous code did, but also casts whatever object PremiumCustomerVariable is pointing to into CustomerVariable (if CustomerVariable and the object are compatible, of course):

CustomerVariable = PremiumCustomerVariable as Customer;
if (CustomerVariable != null)
{
  ...code to execute if PremiumCustomerVariable could be cast as a Customer...
}

If you want to do the same thing using the variable's class (rather than using some object as the previous examples did) then you want to use IsAssignableFrom:

if (typeof(Customer).IsAssignableFrom(typeof(PremiumCustomer)))
{
  CustomerVariable = PremiumCustomerVariable;
}

This also works with interfaces:

if (typeof(ICustomer).IsAssignableFrom(typeof(PremiumCustomer)))
{
  ICustomerVariable = PremiumVariable;
}

What other ways do you use to check? Share in the comments section.

Posted by Peter Vogel on 08/04/2015 at 9:03 AM0 comments


Shrink Your Visual Studio Window (and Put it Back)

I suspect I'm like most developers and keep Visual Studio open and maximized all day (in fact, I've written at least one tip about how to get even more room to edit code). But, I admit, sometimes I switch to other programs. And sometimes, when switching between windows isn't good enough, I need to see that other window beside my Visual Studio window.

You could fiddle with your mouse and window borders. Or, you could hold down the Windows key and press the left arrow button (win_left). The current window will be moved to one side of your screen, have its height set to the full height of your screen and its width set to half of the screen's width. If you switch to another window and press win_left the same thing will happen to that window -- but it will be moved to the other side of your screen so that the two windows display side-by-side. If a window was in maximize mode, it will be taken out of it.

As you might suspect, other combinations of the Windows key and the arrow keys do interesting things. If you press win_up, the current window will be maximized. Both win_right and win_down take the window back to its prior "non-maximized" state (and that half-window display that win_left put you in doesn't count as your prior "non-maximized" state).

And, yes, I realize this isn't really a Visual Studio tip since it works with every window.

Posted by Peter Vogel on 07/30/2015 at 1:06 PM0 comments


Keeping Debugging Data on the Screen

I admit it: I don't use the Watch window much. When I hit a breakpoint and want to know what the current value is in a variable that's near the breakpoint, I'll either type "?variableName" in the Immediate window or hover my mouse over the variable to have Visual Studio pop up a Data Tip with the variable name and value.

If you're a "hover your mouse" kind of person you should pay attention to the pushpin at the end of the Data Tip: If you click on the pushpin and switch it to the "upright" position, that Data Tip will stay on the screen. The next time you hit the breakpoint (actually, whenever you have that part of your code on the screen) the Data Tip will be there, displaying the current value of the variable. If you need to drill down into the variable, you can use the plus sign (+) at the beginning of the Data Tip to see the values on the item's properties.

You can do more with your Data Tip: When you hover your mouse over the Data Tip, a "mini-menu" of choices will appear just past the end of the Data Tip. The middle icon in this mini-menu will let you unpin the tip which does not, as you might expect, cause the tip to disappear. Instead, the tip just drifts off to the right and now appears whenever you hit a breakpoint in any code window. This can be very helpful when you're trying to check one variable's value against another or want to change the value of the variable in the Data Tip. The bottom option in the mini-menu, which lets you leave a comment to yourself, can also be useful if your memory is as bad as mine.

The Debug menu also has some choices for managing Data Tips (including exporting and importing Data Tips if you want to keep some around after your debugging session ends). Data Tips are not an unalloyed blessing, if you have long variable names (names are usually displayed with their complete namespace): If the name disappears off the right side of your screen you won't get a scroll bar that will let you move to the right.

Posted by Peter Vogel on 07/23/2015 at 9:43 AM0 comments


Recycling Action Methods in ASP.NET MVC

Within an Action method, you'll sometimes realize that the processing you need is in some other Action method, often in the same controller. ASP.NET MVC provides a couple of ways of transferring control from one Action method to another one, but, sometimes, the simplest solution is just to call the other method. In those cases, it's worthwhile to remember that when you call the View method in ASP.NET MVC, you're not actually processing a View. The View method merely creates a ViewResult object that, when you return it to ASP.NET MVC, causes ASP.NET MVC to find the View and process it.

In a recent project, many of my controller methods ended by redisplaying the initial page. I had already created a View that did that: It was the first View that's displayed by the controller (I called the Action method that delivered the View FirstDisplay). That method looked like this:

Public Function FirstDisplay (id As Integer?) As ActionResult
  ...code to load the result object with the data to display...
  Return View("DisplayItem", result)
End Function

In my other methods, I could just call FirstDisplay to redisplay the page. FirstDisplay would return the ViewResult object with the correct data, so I just had to return the results of FirstDisplay to get the page I wanted:

Public Function Update (id As Integer?) As ActionResult
  ...code required by the action method...
  Return FirstDisplay(id)
End Function

See? Recycling is good.

Posted by Peter Vogel on 07/15/2015 at 10:55 PM0 comments


Flagging a Page as Dirty with jQuery

In the bad old days of desktop applications, every form object in the world had a Dirty property that let you easily check to see if the user had made any changes to the data on the form. It's almost as easy with client-side code running in the Web browser, provided you use jQuery. This line finds every input tag and ties the tag's change event to a JavaScript function called flagChanges:

$("input").change(function () 
            {
              flagChanges();
            });

That will catch your textboxes, checkboxes, and any other input item defined with an input element. If you also want to catch changes in other elements, you can selectively add additional jQuery statements. This statement will catch changes made from dropdown lists (defined with select elements):

$("select").change(function () 
            {
              flagChanges();
            });

You can do what you want in your flagChanges function, but here's a version that shoves some bolded text inside another element with an id of ChangeTextDiv (based on the name, probably a div element):

function flagChanges() 
{
  $("#ChangeLabelDiv").html("<b>unsaved changes in page</b>");
}

You'll need to remember to clear that element whenever you let the user save their changes. That's what this line of jQuery does:

$("#ChangeLabelDiv").html("<br/>");

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


Integrating Ajax and Partial Views in ASP.NET MVC

In previous columns, I've discussed options in assembling your View from a set of partial Views. However, in all of those examples, I've been assembling a View on the server in response to a request from the client.

The cool thing is that you can also return partial Views to Ajax calls. Here's a getJson call to a ASP.MVC Controller's Action method that expects to get back a set of HTML that it inserts into a page's div element:

$.ajax({
        data: InfoAndData,
        datatype: "text/plain",
        type: "POST",
        url: 'MyController/MyAction',
        cache: false,
        success: function (data) {
                $('#divDisplay').html(data);
            }
        });

The Action method, accepts the data from the Ajax call in the same way as it does any other request but uses the PartialView method to trigger processing of the partial View and have the resulting HTML sent to the client:

Public Function MyAction(InfoAndData As InfoClass) As ActionResult
   ... code to retrieve data based on values in InfoAndData ...
   ... load results ... 
  Return PartialView("MyView", results)
End Function

There are lots of things to like about this approach -- having your HTML generated in a View is consistent with the way that the rest of your HTML is created. You also have access to all of Razor's tools for creating HTML (including localization). Finally, of course, your client-side code is reduced because you don't have to write the code to insert each data item into the page.

But there are at least two things to dislike: The payload being returned (HTML + data) is almost certainly going to be larger than the equivalent JSON object holding just the relevant data. The cycles required to generate the HTML may or may not be equivalent to cycles required to insert the data/set up the HTML on the client.

However, the server-side cycles are on a shared resource while the client-side cycles are on the user's computer. Using server-side cycles makes your application less scalable (personally, I feel that the user's computer should be regarded as free, unlimited resource that should be exploited mercilessly).

For me, I like using partial Views enough (and regard the costs of sending partial views as sufficiently low) that I frequently use this technique.

Posted by Peter Vogel on 06/30/2015 at 10:32 AM0 comments


What's New in Visual Basic 14: Parameterless Constructors in Structures

While everyone using the .NET Framework creates Classes, not many developers create Structures. For those of you who are creating Structures, Visual Basic 14 has some good news for you: You can now give your structure a constructor that doesn't accept parameters (a default constructor). Formerly any constructor you added to a Structure had to accept at least one parameter.

Here's an example of a Structure with a default parameter:

Structure ProcessData
   Private ErrorCount As Integer
   Sub New()
      ErrorCount = -1
   End Sub
End Structure

If you want to have your default constructor actually execute, however, you must use the New keyword. This code will call the constructor and set ErrorCount to -1:

Dim pd As New ProcessData

This code will not:

Dim pd As ProcessData

and it will still run. Nifty, right?

Posted by Peter Vogel on 06/18/2015 at 10:21 AM0 comments


Upcoming Events

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.