Monthly Archives: April 2011

WebMatrix doesn’t Publish All my Files

I’m trying to publish my project to a local website running under IIS 7 on my dev machine and I noticed that some of my .cshtml files were not being published. How does that happen??

It turns out that WebMatrix caches the list of files and whether or not they’ve been changed since the last publish action. But if for example you’ve gone and manually deleted some files from your test website (as I’d done), and then tried to publish them again – when there had been no changes to them – it will think they aren’t changed, so therefore don’t need to be sync’d again.

This is the default behaviour of WebMatrix thanks to a nice little checkbox that is tucked away in the options settings. Go to the Application menu and click on the Options menu item. The Application menu is the menu to the left of the Home tab:

When the Options dialog appears, click Publish on the left hand side and you will see that the first checkbox is ticked by default:

Uncheck the first option and all of your project files will be sync’d each time you go to publish your site. You will still be able to manually de-select any files you want when the Publish dialog is opened.

Lastly, if you are using a a version control system (you are aren’t you?? :o) ) such as Subversion (SVN) you don’t want all the SVN admin folders and files published to your production website. So it’s a good idea to also check the last checkbox on the same screen so that they can be filtered out:

You may need to close and restart WebMatrix for these changes to take effect. The first time I tried it, it didn’t seem to work properly, so I shutdown WebMatrix, restarted and tried again, this time successfully.

You can also clear WebMatrix’ cached list of published files. See here for details.

Informative Error Messages

I just came across this tonight… I have a column called Quantity(int) defined in one table, and another called exactly the same name in another table. Only this time I set the type to be bigint instead – without realising it.

It just so happens when I render the Quantity value to a WebGrid I use a @helper to do some calculations and format it nicely. The WebGrid that renders the data from the table with the int value Quantity worked perfectly. So I copied and pasted the helper code into the WebGrid for the second (bigint) Quantity expecting it to work just the same.

Instead I got a bizarre error message from the Runtime Binder telling me that the best overloaded method match for my method “has some invalid arguments“:

The best overloaded method match for ‘ASP.MyHelper.GetPositionValue(decimal, decimal, decimal, decimal, int)’ has some invalid arguments

This is the offending line in my grid declaration:

I must admit that I sat and stared at the screen for a long, long, time trying to figure this one out. I thought it must have been a null coming from the database as there were some columns that allowed nulls. I checked my default values to make sure they were right.

I finally picked the error and got it sorted – changing the Quantity column from bigint to int. I just wonder how much faster I would have worked it out if the error message had given me type narrowing/potential data lost error, or an invalid cast exception? To me it didn’t seem like the error message I got was the most informative nor pointed me to the real cause of the problem.

ASP.NET/Razor Custom Helpers, DLL’s & Unit Tests

All of the tutorials and sample code I seem to come across for writing a custom @helper using Razor syntax seem to only show how to pass string parameters. I’m building a website that uses bigint, int, nvarchar, datetime and money types in the database.

Obviously bigint maps to long, int to int and nvarchar to string, but for some reason I couldn’t seem to figure out what to map the database money type to, or check for null against a datetime (DB) value. Maybe there is a mapping table specific to razor out there, but I couldn’t find it.

In the end I figured out that the database Money type maps to the .net Decimal type. So the @helper call in my .cshtml file to get the profit from a sale, looks like this:

@MyHelper.GetProfit( @item.Buy, @item.Sell, @item.Qty )

The @helper implementation is:

@helper GetProfit( decimal buy, decimal sell, int qty) 
{
    var zero = new Decimal(0.0);
    if ( qty > 0 && sell > zero )
    {
        var profit = (sell – buy) * qty;
        @string.Format(“{0,0:C2}”, profit);
    }
    else
    {
        var str = “n/a”;
        @str;
    }
}

This seems to work well and prints out a nicely formatted $10,170.00, –$1,340.00 or n/a thanks to the {0,0:C2} formatter string.

If you are editing some values and need to process them on the postback for storing in the database, you need to figure out if you are working with the string value from the form data, or need a strongly typed object ready to pass to your db.Execute( ) statement.

In the top of your .cshtml file you are going to need something like this:

    var buyPrice = “$”;
    var sellPrice = “$”;
    var quantity = “”;
    var sellDate = “”;
    SqlDateTime sellDateDT = DateTime.Now;

To perform validation and any data manipulation you will need to work with the ‘var‘ values (ie. string’s). eg: testing if the date entered by the user is a valid date etc… Once you’ve done that, you have to decide whether to pass a DateTime object, set to the entered value, or a null value (if allowed in the database). For that, you are going to need an SqlDateTime object – set to the correct value, or else set to SqlDateTime.Null.

As I started to create more and more .cshtml pages with these sorts of values to stored in the database, I realised that I needed some utility methods to perform the repetitive, mundane tasks of sanitizing the data received from the posted form.

This led me to write my own little custom .dll with a series of utility classes. I put all of the sanitise methods in there. Some include:


public static string SanitiseCurrency(string input) {}
public static SqlDateTime SanitiseDate(string input) {}
public static string SanitiseWholeNum(string input) {}
public static string SanitiseStr(string input) {}

A sample implementation of one of these santitise methods could look something like this:


public static SqlDateTime SanitiseDate(string input)

{
    SqlDateTime result = SqlDateTime.Null;
    try 
    {
        if (!string.IsNullOrEmpty(input))
            result = SqlDateTime.Parse(input.Trim());
    }
    catch (Exception)
    {
        result = SqlDateTime.Null; // just to make sure
    }
    return result;
}

Notice that most methods return a string object, which works nicely for using parameterized SQL Queries, but the DateTime method must return a strongly typed instance to satisfy the DB driver type mappings etc…

I edit and compile this .dll in Visual Studio 2010, and have a post build success event that copies the output assembly into the /bin folder of my WebMatrix project. It’s so simple to do, no playing with paths, or imports or assembly references etc… Just drop it in the /bin directly and it’s immediately available to your Razor code.

Now, some might think this is a little overkill, but there is a nice side effect – I can create a Unit Test Project under the same solution that holds my utilities project. And suddenly I can edit, build, and test my code! If it passes all my test, I can deploy it to the WebMatrix /bin directory with confidence that my financial/money utility methods are correct with their processing.

Another benefit of having an external project like this, is that you can also call out of your @helper code into your C# .dll and gain the benefit of the feature rich environment in Visual Studio if your @helper performs some complex operations or calculations. This allows you to unit test your @helper too!!

So using the example from the very start of this post again, once I have moved the @helper code out into my utility project, it now looks like this:

@using MyApp.Core;
@helper GetProfit( decimal buy, decimal sell, int qty)
{
    @Utils.GetProfit( buy, sell, qty );
}

Don’t forget to import any namespaces you have used in your .dll, otherwise ASP.NET won’t find it when it attempts to compile the page.

So I now have nice clean HTML code in my .cshtml file; I have nice clean code in my @Helper code; and I have a set of fully unit tested utility functions I can access from my custom .dll.

Very Nice!

IIS 7.5 Unable to serve .cshtml files

I’m playing with WebMatrix and deploying my web site, but when I try to access it, I get the following error:

HTTP Error 404.17 – Not Found. The requested content appears to be script and will not be served by the static file handler.” 

After a bit of hunting around I found that the default .net framework associated with an Application Pool under IIS 7.x seems to be v2.0! To run a Razor site (and display .cshtml files) you must have .Net Framework v4.0 selected for the assigned application pool.

  • To do this, open up the IIS Manager Console (inetmgr.exe). 
  • Expand the hostname node in the “Connections” panel on the left hand side. 
  • Select the “Application Pools” node. 
  • All the App Pools will display in the centre pane, with their details, including which .Net Framework they are running.
  • If your site’s application pool is showing v2.0, double click it and change it to “v4.0 Integrated/Classic” (which ever you need) and then click the OK button to save it. 
  • With the app pool still selected in the main pane, click the “Recycle…” link in the “Actions” panel on the right hand side. This will ensure that the app pool is recycled and restarted with the correct .Net Framework loaded. 
  • Now go back to your website and reload your .cshtml file. It should appear as expected!