Discussing ASP.NET MVC Model Binding With Hidden Data

If you have taken over an MVC application, you may have come across a dilemma like the following. Notice that in a view, within a form, you’ll see a group of hidden fields mixed in with a form like the following.

Html.HiddenFor(i => i.ContactID)
Html.HiddenFor(i => i.ContactTypeID)
Html.HiddenFor(i => i.ContactDescription)
Html.HiddenFor(i => i.ContactTypeDescription)
Html.HiddenFor(i => i.OrganizationID)

Html.LabelFor(i => i.OrganizationName, new { @class = "control-label" }) Html.TextBoxFor(i => i.OrganizationName, new { @class = "form-control" })
@* and so on *@

My example had five hidden fields, but I’ve seen a lot more. These fields are not useful to the form per se; the user doesn’t enter them. However, the information is important to the records about to be updated in the database, and thus are included in the form as hidden fields for that reason. However, another reason is it acts as a quasi-ViewState mechanism that makes it very easy to replenish the following model:

public class ContactInfoModel
{
    public int? ContactID { get; set; }

    public int? ContactTypeID { get; set; }

    public string ContactDescription { get; set; }

    public string ContactTypeDescription { get; set; }

    public int? OrganizationID { get; set; }

    public string OrganizationName { get; set; }

    /* and so on */
}

[HttpPost]
public ActionResult Contact(ContactInfoModel model)
{
 ...
}

While OrganizationName and the other unlisted properties came from the form, the first five properties (and potentially more) are stored in the hidden field. The hidden field makes it nice and easy to replenish this model, and than allow the developer to use the parameters in the post action. MVC does a very nice job posting the values back to the server and populating these properties.

However, notice I said before, that this was a ViewState-like solution? It’s not quite within the model of ViewState because all of the parameters are embedded in the form in clear text. In most systems, the user is required to login before they can ever get to a page that contains this type of information. Either way, the users have the tools (IE developer tools, Firebug) to inspect and change the values in the hidden fields if they so desired. That is where the danger can lie.

Here’s the other side of the conundrum: if we don’t reload the parameters, what do we do? If we didn’t include the hidden fields, the first five parameters are not loaded from the client and thus the model is partially replenished. In most cases, these pieces of information might not be needed anyway (with the exception of OrganizationID in our scenario).

The application can certainly requery the information it needs, but then the information gets reloaded on every postback, which can get more expensive. The application could also use Session to store the information fields too.

I’m not saying “NEVER use hidden fields”, but I’m debating the value of a large number of hidden fields for replenishing the model. I probably fit within the category of storing any relative information in Session or requerying the information from the database, depending on how much information we are talking about. What is your thoughts or preference? Using hidden fields, session, database?

Advertisements

Rendering Markup Anywhere in MVC

I had a hard time coming up with the title, because as you know, markup is pretty dynamic in MVC. However, I came across an interesting limitation when it came to rendering markup. I’m not talking about rendering partial view content using Html.Partial, or using a helper method. I’m actually talking about rendering markup segments, which I’ll demonstrate with a VB.NET example (sorry, I’ve been stuck in the VB world for some time, it’s become more natural than C#):

@* SomeView.vbhtml *@
@Code
Html.ScriptDefine(
   @
      alert("ME");
   )
End Code

Html.ScriptDefine is not something Microsoft created, but a custom extension I created. This was a helper method to register script segments. It is not a method defined globally or in a view, but a helper that’s code, which can be easily reused across projects, which is why I tried to utilize this technique. Somewhere in the master page, a process read all of these scripts and rendered them in the master page. This was excellent; I could define these script blocks anywhere in the view, and they would all get rendered in one place.

My helper looked like the following:

Public Sub ScriptDefine(Of TModel)(html As HtmlHelper, key as String, fn as Action(Of TModel))
    Dim script = fn(html.ViewData.Model)
    'Store reference to model and script somewhere, 
    'which the master page retrieves all of the scripts and renders
End Sub

It worked, except in one scenario: Partial Views, which is a key reason why I wanted it. See, I often found myself using scripts in a partial view. I tried using an optimization technique where scripts run at the end of the page; the only problem was a partial view that used a script had it’s <script /&rt; block defined wherever the partial was, which was usually above the end of the view. The issue with partial views has to do with the rendering process, and although I wasn’t quite sure how to figure out why, I found a better solution anyway: HelperResult.

By defining the script in a helper (a small caveat) and then storing the helper result, this solved the problem much more easily. I was able to define an extension like the following:

Public Sub ScriptDefineHelper(Of TModel)(html As HtmlHelper, key As String, fn As Func(Of TModel, HelperResult))
   Dim helperResult = fn(html.ViewData.Model) 'Returns the content as IHtmlString
   Dim list = CType(html.ViewContext.HttpContext.Items("_Scripts_"), List(Of String))

   if (list Is Nothing) Then
      list = new List(Of String)
   End If

   list.Add(helperResult.ToHtmlString()) 'Store the scripts as a string, which is easy to render later

   html.ViewContext.HttpContext.Items("_Scripts_") = list
End Sub

Now wherever we use our helper, we can use it like:

@Code
  'Use in view or partial view
  Html.ScriptDefineHelper(Function(i) Scripts())
End Code

@Helper Scripts()
   
      alert("Hello");
   
End Helper

And we can render out all the scripts with the following code (we can also use a helper method for this):

Dim items = CType(html.ViewContext.HttpContext.Items("_Scripts_"), List(Of String))
For Each item in items
  @Html.Raw(item)
Next

The real question is why do all of this, when all of the scripts could be in the page? Well, there are good reasons for doing this. First and foremost, keeping the scripts used in a partial view are best defined in the partial view. Out of sight is out of mind, especially for JavaScript. By using this technique, scripts can be defined, and rendered at the designed area, more effectively. That is the primary benefit; outside of that, there aren’t a lot of benefits.

Custom ASP.NET MVC Helper Extensions

As you probably are aware of, ASP.NET MVC was a divergence from the approach developers took to developing ASP.NET web forms applications. For web forms developers, any level of customizations occurred by creating custom ASP.NET server controls, inheriting from a particular base class and adding some functionality, something like:

public class SuperLabel : Label
{
   // Enhanced functionality
}

There are many benefits to doing this; you can initialize the control’s properties for your web application, or encapsulate repeatable code into a common class that’s reused throughout the application. For instance, if we know that we will always render our form labels in a specific manner, I could create a custom control to do this following:

public class FormLabel : WebControl
{

   protected override void Render(HtmlTextWriter writer)
    {
         writer.Write("<div>" + this.Text + "</div>");
    }

}

And that way, every label is wrapped in a div with a FormLabel class. This is a simple example of standarizing your control’s output and thus your client’s markup, but you get the idea. This is also possible in ASP.NET MVC, with the help of your own helper methods.

Note that there are two kinds of helper methods in MVC: ones who return an MvcHtmlString object and render the text inline, and ones that render inside the method and are defined as @Html.DoSomething(); (with a semi-colon at the end; in VB this method can be called in a @Code block). I’m going to talk about helpers that return an MvcHtmlString in this blog post. As a simple example of a helper we may want to standardize on, we can, for instance, wrap a DIV with a special class around the Html.EditorFor helper as in the following example:

public static class HtmlHelperExtensions
{

  public static MvcHtmlString CustomEditorFor(this HtmlHelper html, Expression<Func> expr)
  {
     return new MvcHtmlString("<div>" + html.EditorFor(expr) + "</div>");
  }

}

As you can see, we have a custom editor with a wrapper DIV around it now, which we can put in our UI by doing:

@Html.CustomEditorFor(i => i.ModelProperty)

The TModel and TProp generic references above are inferred from the current view’s model, and the property expressed in the lambda expression. If you look in other MVC helpers, they are all defined with these two generic references. The HtmlHelper class has a lot of useful features; first it has access to all the extension methods as you would use them in the UI (most defined in the System.Web.Mvc.Html namespace, but there are additional namespaces too). It also has a reference to the ViewContext and to the current model for the given view, via the HtmlHelper.ViewData.Model property (remember HtmlHelper is specific to the model, therefore it maintains an explicit, strongly-typed reference to said model).

I’ve only scratched the surface, but you can see a lot of options are available to you. For instance, if you use Twitter bootstrap, maybe you want your editor helper to look like:

 public static MvcHtmlString CustomEditorFor(this HtmlHelper html, Expression<Func> expr)
  {

     return new MvcHtmlString(
  @"<div class=\"control-group\">" + 
    html.LabelFor(
        expr, 
        new { @class = "col-md-2 control-label" }
     ).ToHtmlString() +
   @"</div>
     <div class=\"col-md-10\">" + 
    html.EditorFor(expr) + 
    "</div>");

  }

And thus, this saves you from writing a lot of HTML. In the future, I may write on some of the extensions I’ve used for twitter bootstrap to save time. I hope this is a good overview of how you can customize HTML helpers in ASP.NET MVC, which I am using this technique in a current ASP.NET MVC 5 application.

Introduction to Knockout JS, Part 1: Basics to Binding

Knockout JS is an MVVM tool for client-side JavaScript.  Knockout performs binding of a view model class to the view, which the view consists of an ordinary HTML document with a data-bind attribute.  The data-bind attribute contains binding information that Knockout uses to supply data from the view model to the view.

Let’s learn the basics of Knockout JS hand’s on.  To start,  below is a sample view model that we’ll attach to the view.  the viewModel class defines an observable property, which an observable is essentially a two-way binding between view and view model.  When the view changes, the view model is updated, and vice versa.

<script type=”text/javascript”>
var viewModel = {
currentValue: ko.observable(1)
};

ko.applyBindings(viewModel);
</script>

Notice the last line, ko.applyBindings; this applies the view model to the view; a second argument exists, allowing us to specify the ID of a region of the application to apply the model to, rather than applying it to the whole document.

To load up the currentValue property in the UI, we can assign it to a textbox like the following:

<input type=”text” data-bind=”value:currentValue” />

Knockout uses a binding structure of <binding>:<property or expression>.  In this case, since it’s an input, we use the value binding, and load in the currentValue property.  A span would use the text binding, as shown below, and a div would use the html binding.  The different between binding is essentially the attribute the binding is applied to, but is not always the case.

<span data-bind=”text:currentValue” />

<div data-bind=”html:currentValue” />

Attributes can also be bound; assuming we wanted to set a random value attribute on a link, we can create a new attribute using the attr binding, as shown below.  The attr binding uses as JavaScript class like notation to define the attributes.

<a target=”_blank” data-bind=”attr: { someattrib: currentValue }”>Sample Link</a>

Attribute expressions can also be chained using a syntax like the following:

data-bind=”{ html: htmlItem, attr: { href: attrItem } }”

What does this mean to us?  At runtime, Knockout applies the value from the model to each of the elements within the document.  As UI elements report a change (such as a blur event from a textbox), a call to the view model is made to update it and any other element referring to this property.  This only works if you use the ko.observable() function.

Bindings can become more complicated by forming expressions, which are longer statements evaluating the actual properties and checking a value within a range, list of acceptable values, etc.  For example, here is a more complex form of binding:

<span data-bind=”{ visible: currentValue() > 10, css: { Yellow: currentValue() < 30, Red: currentValue() >= 100, Orange: currentValue() >= 30 && currentValue() < 100 } }”>

This definition establishes the visible and css bindings, which within the css binding is several complex expressions.  We’ll get into CSS expressions later; for now, know that these expressions can be evaluated within a data-binding statement to. Notice one change in syntax; when using an expression, we use currentValue(); this is because ko.observable is actually a function (because of problems with the notion of properties related to IE).  If we had a reference to the view model, we could programmably set the currentValue using viewModel.currentValue(20), or get the value using viewModel.currentValue().  When supplying the property directly in the data-bind statement, we do not need parenthesis, using data-bind=”text:currentValue”.  When used in an expression, though, we do need the parenthesis as it’s the equivalent of manually invoking members of the view model programmatically.

That’s all the fun we have for KO bindings for now.  We’ll take a look at some of the other bindings in a future blog post.