Skip to content

Great CS Textbooks, Cheap

I’m probably late to this party, but I’ve discovered that you can find incredible deals on used CS textbooks at Amazon, especially for older editions.

For example, I recently ordered a copy of Programming Language Pragmatics, by Michael L. Scott. It’s $63 new for the hardcover or $43 on a Kindle. I got a used copy of the (somewhat older) second edition for $3 + postage, for a total of $7. True, I don’t get the new chapter on VMs, but I can live with that. The third edition totally dried up the market for the second, so there are really good deals available!

The book itself is good so far, though I haven’t read enough to give a full review. It covers substantially similar territory as the dragon book, except more scope talking about programming languages and computer architecture and less depth talking about compiler internals. They’re both worth reading.

Tagged ,

An Excuse Not to Roll Your Own Authentication Scheme

The Rails 3.1 Release Candidate announcement contained news of many new and useful features, plus these regretful words:

has_secure_password: Dead-simple BCrypt-based passwords. Now there’s no excuse not to roll your own authentication scheme.

I will briefly provide an excuse.

"Simple BCrypt-based passwords" is a reasonable feature, but shouldn’t be mistaken for end-to-end authentication, or even a substantial subset of that problem. Web site authentication in the real world is a far harder problem than salting and hashing a password — which BCrypt does OK, as far as I know. You can prove this to yourself merely by observing that many frameworks which have correctly implemented salting and hashing have nonetheless had their authentication systems compromised by other means.

Having (correctly) validated a username and password, most web authentication frameworks use an encrypted authentication token stored in a cookie (or some other place) for future requests. This way the client (the browser) doesn’t need to remember the password or repeatedly prompt the user for it. However, once the token has been issued, having a copy of it is as good as having the password (for a short period of time, anyway — they typically expire). That’s how tools like Firesheep work on un-secured networks. If you produce or handle this token incorrectly then may as well not bother doing username and password authentication in the first place!

Remember last year when the ASP.NET membership provider used in large numbers of ASP.NET sites was discovered to be vulnerable to a padding oracle attack? ASP.NET, as far as anyone knows, is salting and hashing its passwords correctly. But that’s not enough to stop people from breaking into the system. The other links in the "security chain" have to be secure as well. In the case of ASP.NET, the server leaked information which was useful when attempting to break the encryption of the authentication token. This is sometimes called a side channel. Having succeeded in breaking the encryption, a client could then create a "fake" authentication token which the server would mistake for one it had issued itself. Hence, it was possible to break into a site without ever knowing the password. The authors of this exploit had formerly found similar vulnerabilities in JSF and other frameworks.

All of this adds up to old news: Security is hard. Even experts in the field make mistakes that other experts in the field overlook for years. Anyone can build a system which they themselves can’t break into. The best solution for developers of sites not specifically intended to prototype new and potentially vulnerable security systems is to use proven, off-the-shelf authentication systems, and to instead put their efforts into delivering value to their end users!

Tagged , , , ,

Why Won’t Visual Studio Step Into This Code?

I helped another developer debug an interesting problem this morning. Let’s see if you can spot the problem. The code in question looked something like this simplified version containing only enough code to show the problem:

public void Execute()
{
    DoStuff();        // breakpoint 1
}

public IEnumerable<Coordinate> DoStuff()
{
    LaunchMissiles(); // breakpoint 2
    // rest of method here
}

Note that the result of the function DoStuff is not used by Execute. That result actually exists only for testing purposes; it’s essentially a log we use to monitor changes the method makes to external state. The unit tests in question passed, so it was clear that DoStuff worked correctly, at least in a test context. The problem was that when the code ran outside of a test context (i.e., in the real application), the DoStuff method would never run. The debugger would stop at breakpoint 1, but not at breakpoint 2, but only in the "real" application. Similarly, attempting to step into DoStuff would not actually go into the method body. If we debugged the unit tests, the debugger would stop at both breakpoints, and the method worked.

Can you spot the bug?

Perhaps it would help if I showed more of the method:

public IEnumerable<Coordinate> DoStuff()
{
    LaunchMissiles(); // breakpoint 2
    yield return CurrentCoordinates();
}

Now do you see the bug? Remember, the unit tests pass. There is no special knowledge about our application needed to see the problem here; all of the information required to spot the bug is in the code snippets above. The problem is a code bug, not a setup or configuration issue.

Perhaps it would help if I showed you a version of DoStuff which "works."

public IEnumerable<Coordinate> DoStuff()
{
    LaunchMissiles(); // breakpoint 2
    return new List<Coordinate> { CurrentCoordinates() };
}

With this version, both the unit tests and the "real" application work correctly.

The Solution

At first glance, this might seem puzzling. I’ve changed only the last line, and both of those versions appear to do almost exactly the same thing. Why is the behavior of the breakpoint at the previous line different?

The answer is that using yield return causes the C# compiler to change the entire method, not just that single line. It surrounds the code with a state machine containing the rest of the method body. Importantly, the iterator returned from the "yield return" method is entirely lazy; it will not run the method body at all until you attempt to iterate the result of the method. But Execute ignores this result, so the method never runs at all.

Discussion

Some languages, like Haskell, go to great lengths to segregate expressions and side effects. C# isn’t one of them, but even so it’s common to try to improve quality by doing so. Eric Lippert, a member of the C# compiler team, once wrote:

I am philosophically opposed to providing [an IEnumerable<T>.ForEach() method], for two reasons.

The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects.

The purpose of an expression is to compute a value, not to cause a side effect. The purpose of a statement is to cause a side effect.

It is clear that causing side effects could cause an expression to change in mid-computation. This is problematic for debugging and quality, especially if some of the evaluations are lazy. But as this example demonstrates, the opposite is also true: Adding expressions to a computation can change the side effects, too.

Tagged , ,

A Better View API for Grids in ASP.NET MVC

I’m writing a grid-independent interface for displaying data in ASP.NET MVC applications, and I would like your feedback on the API design.

In my last post, I discussed some of the problems with existing grid components for ASP.NET MVC. Actually, there are a couple more design issues which I forgot to mention in that post. I’ll discuss them briefly before talking about View design.

  • Many grids require two requests in order to display the first page of data: One for the page itself, then a second, AJAX request for the data. I can understand why the AJAX request is necessary for the second page of grid data, but shouldn’t the first page just come already populated? Making too many requests is one of the most common causes of performance problems in web applications.
  • Many grids require executing a JavaScript method in order to set up the component. Unfortunately, they unnecessarily wait until the jQuery.ready event fires, resulting in unnecessary visual disruption and poor performances the page loads. It’s often unnecessary to wait for the ready event, so you can visibly improve the perceived performance of the page by simply calling that method sooner!
  • The two problems above compound each other. If you wait until the ready event fires to even issue a request for data, and then wait some more for that data to return, that can be a lot of waiting!

Displaying Models in MVC 2

In ASP.NET MVC 1, you had to write specific markup in each view, in order to display each individual property of the view model correctly.

In ASP.NET MVC 2, there is a standard way to render the entire model for your page, no matter what kind of data you plan to show:

<%: Html.DisplayForModel() %>

When you do this, MVC will look up the correct template for your model, or its sub-properties, based on its type, and render it appropriately. You can easily customize this with user controls, at any level of your application. You can read about the details on Brad Wilson’s blog.

(Unfortunately, MVC 2’s VS tooling does not use this pattern when it generates new views. I believe this is fixed in MVC 3.)

If you want to render only a certain property of the view model, rather than the entire model (perhaps you have other properties on the view model which control page layout, and are not intended for the final, rendered page itself) then you use:

<%: Html.DisplayFor(m => m.MyCoolGrid) %>

Only if you want to render a control with customizations which cannot be inferred from the metadata on your view model should it be necessary to specify a specific control:

<%: Html.Grid(Model.MyCoolGrid, new { @class = "importantGrid" } ) %>

A Better Grid View API

Oddly, the demo code for most grids supporting MVC seems to favor the third form over the first two. To me, the third form is the exception, and the first two should be the standard methods for most pages. So the "ideal grid API" for views is really no API at all; you simply use the built-in methods which are already favored by MVC for every other kind of model.

Namespace Issues

In a non-trivial MVC application, it is very easy to go overboard with extensions to HtmlHelper. Some components, like Telerik’s suite for ASP.NET MVC, fight this by adding a single extension method, and then putting their components into this "namespace":

<%: Html.Telerik().Grid(Model) %>

I think that this attempt to fight clutter is admirably intentioned, but probably unnecessary. If you’re only going to use Telerik’s controls on a single page, then you can easily Import that namespace on just that one page, instead of specifying it in web.config. If, on the other hand, you intend to use them in most pages in your application, then the extra .Telerik() call in the code above is just noise. Yes, existing code might have a Grid extension method for HtmlHelper, but it is unlikely to specify Telerik’s model as its first argument, so it should not actually conflict.

So, in my initial design, I’ve opted to not do this. However, I remain open to arguments as to why I should. There doesn’t seem to be any clear right or wrong.

Custom Options

Of course, sometimes you do need to use the third form, because the model supplied by the controller is not enough to totally specify the custom needs of a particular page. MVC’s convention for this appears to be to supply large numbers of different overloads for each control, representing every possible combination of options imaginable. (There are, for example, 10 different overloads of Html.ActionLinkcausing no small amount of confusion to MVC developers.)

Instead of overloads, I decided to use a strongly-typed options object. This requires a few more keystrokes, but the resulting code is much more readable, and, as I noted above, even calling the Grid method directly at all is the exception rather than the rule.

Here, for example, is how you might choose to override default options for one specific grid:

<%: Html.Grid(Model, new GridViewOptions
                         {
                             Multiselect = true,
                             Pager = false
                         } ) %>

This is much easier to understand than:

<%: Html.Grid(Model, 18, false, "Foo!" ) %>

I can also change the rendered grid to something other than the default grid for the project:

<%: Html.Grid(Model, new GridViewOptions
                         {
                             Renderer = new JqGridRenderer()
                         } ) %>

In many cases, this will be the only code change necessary in order to display a different grid, despite the fact that, for example, plain HTML tables and JqGrids work very differently!

What’s Not There

Please note that there is no need to define grid columns, headers, alignment, etc., in the view. This can all be inferred from model metadata!

A Fluent Interface?

Another possible approach, which some people like, is to use a so-called "fluent" interface. Telerik does this for their grid. With this approach, my example above would look like:

<%= Html.Grid(Model).EnableMultiselect().NoPager() %>

Note carefully, however, that I had to change the "safe" <%: syntax introduced in .NET 4 to the old, "unsafe" <%= syntax from .NET 2. The code above only works because the .ToString() method on the returned type is overridden to return markup — as a string, not as an MvcHtmlString! The <%: syntax handles encoding strings automatically, and, in my opinion, the <%= syntax should not be used at all in .NET 4. A "beautiful" API which requires using features which make your site vulnerable to XSS attacks is not a step forward, in my opinion!

I can’t think of a way to make the "fluent" approach work with the .NET 4 syntax. The Grid method is going to return HTML markup, so it should not be encoded. However, the "fluent" interface requires returning a type containing the fluent methods, which will not be MvcHtmlString. So a call like this:

<%: Html.Grid(Model).EnableMultiselect().NoPager() %>

…would return encoded output (e.g., "&lt;table&gt;"); not what we want! And this:

<%: Html.Grid(Model).EnableMultiselect().NoPager().ToHtmlString() %>

…is just ugly! If the user forgot the .ToHtmlString() bit, they would get no error, but get encoded output at runtime. Yuck!

I don’t want to close the door to a "fluent" interface permanently, since some people like them, and those who do not like them would not need to use it, but I’m not going to write it unless I can find a way to do it well, and I haven’t been impressed by what I’ve seen in other projects. If you’re reading this and you’re aware of a technique for overcoming the issues I’ve described here, please enlighten me!

The Part with the JavaScript

Many grids require calling a JavaScript method, often with a big JavaScript object specifying the configuration of the grid. Now, one of the original tenets of ASP.NET MVC, from day one, was "control over every angle bracket in your page."

Unfortunately, this dictum has not always been followed when it comes to the generated JavaScript. MVC 2’s validation support, for example, injects its script into the middle of your page, and you cannot change this. (MVC 3, however, fixes this.)

I have seen commercial grid components for MVC which inject a giant $.ready event handler right into the middle of the rendered markup! I’m not going to name names, but before you pay for a commercial grid, look at the markup on their demo site! In fairness, there are also commercial grid components which handle this better.

Anyway, in addition to an HtmlHelper extension for the HTML markup, we also need an extension for including the necessary JavaScript (if any; a "plain HTML table" grid renderer might not require any JavaScript at all) references in the rendered page:

<%: Html.GridScriptTag() %>

What this method really means is, "If any of the grids I have included in the page thus far require JavaScript code, please put that script right here." Because this method has a fairly low overhead and emits no markup if you haven’t actually used any grids on the page, you can put it in your Site.Master, if you prefer. Importantly, however, you can also put it somewhere else. This allows you to optimize the point at which the JavaScript method is invoked, should you need to do that.

This method has an overload which takes a strongly-typed options object. You won’t typically need to use this, but you might have JavaScript which you would like to include if and only if there is at least one grid present on the page:

<%: Html.GridScriptTag(new ViewOptions
                           {
                               AfterGridInitializationJavaScript = SomeScript
                           }) %>

"Unobtrusive" Scripting?

MVC 3 has an "unobtrusive" client validation option. Would this even make sense for a grid? I haven’t figured this out yet, but I’m thinking about it.

How Am I Doing?

I’m afraid that’s quite a lot of discussion for what is, in the end, design concerns over the signatures of two methods. If you’re still reading this, thanks!

At the same time, however, I really want to get this right. The controller and view APIs of this library are the parts which I imagine developers will have to grapple with day in and day out. If the internals of the library aren’t pretty in every corner, well, nothing is perfect. But the controller and view APIs are extremely visible, so they deserve a lot of scrutiny!

What’s Next?

In the future, I’d like to similarly examine controller design. But first I have some questions about testing this stuff; it’s tricky! Oh, yes, and I’ll be publishing the code!

Tagged , ,

One (MVC) Grid to Rule Them All

Imagine you’re starting a new project using ASP.NET MVC. Let’s say it’s a project which frequently requires displaying a list of records, like Google or Stack Overflow or an enterprise database application. Which grid should you use?

The obvious answer is, "I don’t know. I’m just getting started. Does it really matter, right now?" Don’t you wish!

There are many grids available for ASP.NET MVC. If you’re prepared to dedicate your project to a single grid at the outset of your project, and never change it, nor support alternate platforms, like mobile, then you can (almost) be a happy developer. But if you think you might want to support mobile devices, tablets, and desktop browsers with the same application, if you acknowledge the possibility that you might want to change your mind about which grid you will use in the future, or if you care about separation of concerns, then you may have a problem.

Most grids don’t support ASP.NET MVC very well. In particular, they often:

  • Push presentation concerns into the controller. In my opinion, the specific grid you choose in the manner in which it is rendered (column headers, search features, paging, etc.) is a presentation concern, and belongs in the view portion of an application with MVC architecture. Controllers should be grid-agnostic, both in the datatypes they use and in the way you structure your actions.
  • Render JavaScript inline. For best page rendering performance, JavaScript should be included at the very end of the body tag.
  • Don’t support DataAnnotations and other features related to MVC 2’s templates. If I have a view model which is marked up with DataAnnotations attributes like [DataType(DataType.Date)], then I should not have to do anything further in order to get a grid to display correctly.
  • Require too much code in too many places to get a decent grid on the page.
  • Don’t support ASP.NET MVC at all. SlickGrid, for example, is a fairly popular JavaScript-based grid which suffers from being minimally documented and does not ship with an MVC interface. This is understandable, because writing a rich integration with ASP.NET MVC is a fair amount of work! What if there were an easier way…?

A while back, I published some simple examples of how to integrate jqGrid with ASP.NET MVC. I’ve used this general technique in real-world projects, but the lack of support for DataAnnotations/templated views in my code was becoming a maintenance issue; the technique I demonstrated there required writing too much JavaScript. I decided to go back and add support for MVC 2 templated views and generate the JavaScript. As I did so, however, I quickly realized that there was very little jqGrid-specific code in my project. I partitioned this off into its own namespace and added a feature allowing the user to specify a grid renderer at runtime. Mixing in fixes for all of the issues above, I now have the skeleton of a generic grid interface in place.

To be clear, I am not writing a new grid. Instead, I’ve written an interface which supports multiple grids, including jqGrid and even plain HTML tables, without requiring special, grid-specific code strewn throughout your application.

I’m releasing this as open source. Actually, it’s already out, but it’s not quite public yet. I have a few more pieces I need to put in place first, like a demo application.

In the meantime, I’d like to get some feedback on the API. My opinion is that most grids which have an MVC integration at all require the programmer to do far too much work in order to get a decently-formatted grid on the page. I admire the emphasis on API beauty which I see in the Rails community.

So I’ll be "releasing" this a little early. It’s not really ready for production use yet. Although the code is solid, I am still making fairly significant changes to the API. I want this to look right, and I’d appreciate the help of anyone reading this blog.

Or, continue on to the next post in this series, examining the API for views.

Tagged , , , ,

How to Avoid Cut and Paste Code with ASP.NET MVC 2 Model Validation

In this post, I will demonstrate how to make your own model validation attributes in order to share common validations throughout an ASP.NET MVC application, and which support MVC 2’s client-side validation feature.

Validating a ZIP Code

As an example, consider a model for an address.

public class EditModel
{
    public Guid Id { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZIP { get; set; }
}

Now I would like to add a validation attribute in order to ensure that only valid ZIP codes can be entered. In the US, a valid ZIP code is either five digits, or five digits and then a hyphen and then four digits, e.g. 43082 or 43082-6999. I can use the built-in RegularExpressionAttribute for this:

public class EditModel
{
    public Guid Id { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    [RegularExpression(@"\d{5}(-\d{4})?", ErrorMessageResourceName = "InvalidZIPCode", ErrorMessageResourceType = typeof(MyApp.Resources))]
    public string ZIP { get; set; }
}

This is enough to give me server-side validation when a model of this type is bound by the MVC framework. If I turn on client-side validation, then JavaScript will be generated to do the same validation on the client, as well.

//...
"ValidationParameters":{"pattern":"\\d{5}(-\\d{4})?"},"ValidationType":"regularExpression"}
// ..

So far, so good.

Don’t Repeat Yourself

If this is the only ZIP code which ever appears in my application, I’m done. But if I have several ZIP codes in the application, I would like to consolidate this code into one place.

Perhaps, in a future release of the application, I will support Canadian postal codes in addition to US ZIP codes. I would like to be able to make this change in one place.

I can create a dedicated ZIP code validation attribute by subtyping the RegularExpressionAttribute.

[AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class ZipCodeAttribute : RegularExpressionAttribute
{
    public ZipCodeAttribute()
        : base(@"\d{5}(-\d{4})?")
    {
        ErrorMessageResourceName = "InvalidZIPCode";
        ErrorMessageResourceType = typeof(MyApp.Resources);
    }
}

…and update the edit model to use it:

public class EditModel
{
    public Guid Id { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    [ZipCode]
    public string ZIP { get; set; }
}

Fixing Client-Side Validation

This looks good, and seems to work, but testing will reveal that MVC 2’s client-side validation feature has stopped working, even though server-side validation will continue to work as expected. Examining the rendered JavaScript will show that the expected regular expression has not been injected into the page.

Internally, MVC stores a dictionary of attributes, and their corresponding client validation adapters. When it comes time to render the page, it goes through the list of attributes, and finds corresponding entries in the dictionary. Because of the way that this is implemented, it will not find adapters for subtypes of known attribute types. This seems like a violation of the Liskov Substitution Principle.

We can work around the problem, though. There is an API for adding additional attributes to the internal dictionary. In Global.asax.cs, you can add the following code to the Application_Start event handler:

private void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
    // ...
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(ZipCodeAttribute), typeof(RegularExpressionAttributeAdapter));

The only comprehensive "documentation" for this that I’m aware of is the MVC source code.

After adding this code, client-side validation will start working again.

Tagged , , ,

Unit Testing Html Helpers for ASP.NET MVC

Html helpers for ASP.NET MVC are static extension methods, which frequently reference the ViewContext and  HttpContext. Combined, this can make unit testing a bit tricky. Let’s write a new Html helper using a test-first methodology. Let’s start with a prototype function:

        public static MvcHtmlString MyTable(this HtmlHelper helper, MyModel model, IDictionary<stringobject> htmlAttributes)
        {
            return MvcHtmlString.Empty;
        }

I’ve added just enough code here to get the prototype to compile. Now let’s write some unit tests. First we need to validate the arguments. I’m using MSTest here:

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void MyTable_should_throw_when_helper_argument_null()
        {
            var model = new MyModel();

            MyHelpers.MyTable(null, model, null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void MyTable_should_throw_when_model_argument_null()
        {
            var hh = new HtmlHelper(null, null);

            MyHelpers.MyTable(hh, null, null);
        }

Note that I have elected to call this method as a regular static method rather than as an extension method. Either one is valid, but since I am unit testing the case where the HtmlHelper argument is null, it makes more sense to call the method under test as a regular static method.

Those tests will fail when run, so I’ll write some code to fix that:

        public static MvcHtmlString MyTable(this HtmlHelper helper, MyModel model, IDictionary<stringobject> htmlAttributes)
        {
            if (helper == null)
            {
                throw new ArgumentNullException("helper");
            }
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }
            return MvcHtmlString.Empty;
        }

Now let’s presume that the requirements of the new method specify that the table should get its HTML id from the HttpContext.Items. This is of course a very stupid place to store an HTML id, but I want to demonstrate how to fake the HttpContext, since that is something that people often find difficult. So let’s make a fake HttpContext. I’ll need a lightweight implementation of IViewDataContainer, as well, for reasons which will be clear later on:

        private class FakeHttpContext : HttpContextBase
        {
            private Dictionary<object, object> _items = new Dictionary<object, object>();
            public override IDictionary Items { get { return _items; } }
        }

        private class FakeViewDataContainer : IViewDataContainer
        {
            private ViewDataDictionary _viewData = new ViewDataDictionary();
            public ViewDataDictionary ViewData { get { return _viewData; } set { _viewData = value; } }
        }

I elected to only implement the Items property of HttpContextBase, since that is the only one I’ll need to reference in the implementation of my helper. Were I to reference other HttpContextBase properties which I did not override, I would expect to see a NotImplementedException at runtime.

With these two, small classes, I can write a test for the helper which will execute without throwing any exceptions. Well, except for the fact that the assertion fails:

        [TestMethod]
        public void MyTable_should_render_HTML_table_with_id_from_http_context()
        {
            var vc = new ViewContext();
            vc.HttpContext = new FakeHttpContext();
            vc.HttpContext.Items.Add(MyHelpers.IdKey, "foo");
            var hh = new HtmlHelper(vc, new FakeViewDataContainer());
            var model = new MyModel();

            var result = MyHelpers.MyTable(hh, model, null).ToString();

            Assert.AreEqual("<table id = \"foo\"></table>", result);
        }

I needed the IViewDataContainer because the two argument constructor for HtmlHelper will throw ArgumentNullException if you pass a null for the second argument.

Finally, I can implement the helper to make this unit test pass:

        public static MvcHtmlString MyTable(this HtmlHelper helper, MyModel model, IDictionary<stringobject> htmlAttributes)
        {
            if (helper == null)
            {
                throw new ArgumentNullException("helper");
            }
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }
            TagBuilder tagBuilder = new TagBuilder("table");
            tagBuilder.MergeAttributes(htmlAttributes);
            tagBuilder.GenerateId(helper.ViewContext.HttpContext.Items[MyHelpers.IdKey]);
            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
        }
Tagged , , , , ,

How Does Html.EnableClientValidation() Inject JavaScript?

For a project I’m currently working on, I have a need to add some JavaScript at the end of a page in an ASP.NET MVC application. Since this is part of what Html.EnableClientValidation does, I thought that I would check out that source code to see if there was any kind of generalized mechanism for this. No such luck, I’m afraid. But I did learn a bit more about how Html.EnableClientValidation works, so I thought I might write that down in case it turned out to be useful someday.

The Html.EnableClientValidation method itself does almost nothing. It just sets a flag indicating that other methods which care about client validation should do their thing. The start of the sequence which concludes with client validation JavaScript being written into the HTML page begins with Html.EndForm. Most people don’t call this directly, instead calling Html.BeginForm inside of a using block, which amounts to the same thing. Html.EndForm, in MVC 2 does two things:

  1. Writes a </form> closing tag. No surprise there.
  2. Writes client-side validation JavaScript.

Therefore, client-side validation will not work if you manually write a <form> tag rather than directly or indirectly calling Html.EndForm. However, you can look at its source code and do the same thing yourself if you prefer to write your own <form> tag.

If this second action is a little surprising for a method called "EndForm" the manner in which it accomplishes this task is even more surprising: It calls a function on the ViewContext type which knows how to write client validation JavaScript onto the page. Perhaps, like me, you’ve always thought of the ViewContext type as simply an aggregation of properties containing information relevant to the (ahem) context in which the current page is being rendered. Well, in addition to this, ViewContext also contains a method which writes JavaScript for client validation. It also contains a const with the hard-coded template for the final <script> tag.

All in all, my conclusion is that the system used to write JavaScript for client validation in MVC 2 is completely hard-wired to that task and not extensible for other purposes.

Tagged , ,

Troubleshooting Entity Framework Connection Strings

In an application which uses the Entity Framework, you may see the following error at runtime:

MetadataException: Unable to load the specified metadata resource

The cause of this error is a missing or malformed Entity Framework connection string. In particular, the cause of this error is the metadata parameter of the connection string. Let’s examine this more closely.

Which Config File?

Before you begin troubleshooting, make sure you are looking at the correct file.

Connection strings are loaded from the configuration file for the executing assembly, which may not be the assembly which contains your Entity Framework model. So if you have a data assembly containing an Entity Framework model and a web assembly containing a web application which references the data assembly, then the Entity Framework connection string needs to be in the Web.config file for the web assembly. The data assembly can have its own connection string, if you like (this is convenient, as it will be used by the Entity Framework designer), but it will not be used by the web application at runtime.

Metadata

MSDN documents EF connection strings generally. But the cause of the error above is specifically the metadata parameter. This parameter tells the Entity Framework where to find your EDMX at runtime. When your application is compiled, the EDMX is split into three parts: CSDL, MSL, and SSDL. For the purposes of this post, you don’t need to think about what they mean right now; it’s enough to know that you need all three of them at runtime.

The EDMX can be supplied to the application as embedded resources or files on disk. The default is embedded resources, so we’ll focus on that case.

The metadata parameter for an application with an Entity Framework model called Model.edmx in an assembly called Simple Mvc.Data.dll might look like this:

<connectionStrings>
	<add name="MyEntities" connectionString="metadata=
            res://Simple Mvc.Data.dll/Model.csdl|
            res://Simple Mvc.Data.dll/Model.ssdl|
            res://Simple Mvc.Data.dll/Model.msl;provider= <!-- ... -->

So you can see there is one reference for each of the three parts of the EDMX that we need at runtime. They all work in the same way, so let’s examine just the first more closely. The CSDL reference looks like this:

            res://Simple Mvc.Data.dll/Model.csdl

It specifies three things:

  1. We’re loading the CSDL from a resource. That’s the "res://" part.
  2. The name of the assembly which contains the resource, "Simple Mvc.Data.dll". If your assembly is strong named, you can specify a strong name, in all its verbose glory, here.
  3. The name of the resource itself, "Model.csdl". Do not confuse this with the EDMX or model name. In this case they happen to be the same, except for the extension, but that’s not always true!

Let’s examine #2 and 3 more closely.

Assembly name

It’s really common to omit the assembly name in a connect string, and use * instead, like this:

<connectionStrings>
	<add name="MyEntities" connectionString="metadata=
            res://*/Model.csdl|
            res://*/Model.ssdl|
            res://*/Model.msl;provider= <!-- ... -->

This means that instead of loading the resource from one specific assembly, the EF will scan all loaded assemblies at runtime. Two obvious downsides to this are that it takes a bit of time to do this, and the assembly might not be loaded yet. The second case is one reason you might get the error at the start of this post. So specifying the assembly explicitly is always a good idea, I think.

Resource names

Remember how I said that the resource name isn’t necessarily the same as the model name? Here’s a real-life example of that. I opened one of our production assemblies in Reflector, and found this:

There’s actually a good reason that those resources have such bizarre names, but it’s a digression and not relevant to this post. The point is that after you’re sure the assembly name is right, the next step in solving the error at the top of this post is to double-check the resource names.

A simpler resource name will look like this:

Remember the "simpler" metadata where I used * instead of the assembly name? You can go even simpler. This metadata, perhaps surprisingly, actually works (with caveats):

<connectionStrings>
	<add name="MyEntities" connectionString="metadata=
            res://*/;provider= <!-- ... -->

This is the "throw everything against the wall and see what sticks" approach to a connect string. It will probably fail if your resources don’t happen to have the same name as your model, or if the assembly doesn’t happen to be loaded. But it (in simpler cases, anyway) frees the programmer from having to think about what any of this stuff means, so it’s a popular solution.

Tagged , ,

New InterBase Partner DVD In Progress

The next version of InterBase is nearing completion, and, as always, will include a Partner DVD with demo versions of third-party tools supporting InterBase. If you are an InterBase Partner, you should have already been notified of how to submit your product.

If you produce a tool or component supporting InterBase and have not already received a notice about the Partner DVD, then please contact Anders Ohlsson (firstname.lastname@embarcadero.com) immediately.

Tagged ,

Bad Behavior has blocked 713 access attempts in the last 7 days.

Close