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

Building a Windows 8 Required Validator Control

Coming from an ASP.NET background, I’ve been used to the way ASP.NET validates user input.  ASP.NET made validation easy; a developer simply dropped a RequiredFieldValidator onto a web form, linked it to the control to validate, supply a set of initialization parameters, and voila, validation problem solved.  Of course, you’d run into some common configuration problems, some easily solved by validation groups, while others solved by some manual method calls.  This worked from the concept of web development, and it has some practicality in a Windows world, and as such, this article is going to look at building a similar capability in WinJS.  Note that I never meant for this component to encompass all validation scenarios, so you may find some faults in my implementation (feel free to point them out in the comments).

To start, we need a class.  Classes have always varied in implementation in the JavaScript world.  The approach WinJS uses is nothing new, but may be a hybrid of existing techniques.  A class starts with a WinJS.Class.define method call.  Define has the following signature:

define(function() { /* constructor */, { /* instance methods */ }, { /* static methods */ }

In our required validator example, we need to define our class as such:

var requiredValidator = WinJS.Class.define(

function (element, options) {
this.element = element;
this.element.winControl = this;        this._errormessage = null;
this._isvalid = true;
this._mode = “text”;
this._targetID = null;
this._text = null;

WinJS.UI.setOptions(this, options || {});

this._buildVisualTree();

var list = window[“Validators”];

if (!list)
list = [];

list.push(this);

window[“Validators”] = list;

},

.

.

);

The first parameter of the define method is the constructor (which is also the only one visible here), which performs a variety of steps.  The first wo steps are common with WinJS controls; we first store the element in an instance field, followed by creating the winControl object reference common through all WinJS component in the framework.  Ever wondered how other windows controls worked when you saw this code: document.querySelector(“#idofwindowscontrol”).winControl?  The setting of the winControl property above establishes the linkage.  Our validator needs to store data in variables defined on the instance (hence the this._X references), and supply them with defaults.  These store the options of the control, and are exposed as properties (which we’ll see later on).  For instance, you probably have seen usage of the data-win-options properties on WinJS control.  Suppose our validator has a configuration of data-win-options=”{text:’$$’, targetID:’#target’}”; the control receives these values in the constructor (via the options parameter), and the values are supplied to the text and targetID values through the control’s properties.  The setOptions method is the way to make this all happen.

Note that the control adds itself to a collection in the windows object; this way, the entire page  can access all of the validators on the view, similar to how ASP.NET provides all of the validators through it’s Page.Validators property.

The next code sample begins our instance methods, or the body of the class.  Notice WinJS (and IE 10 which runs the WinJS application) has a notation for properties using “get:” and “set:”, something that was missing in previous implementations of IE.  The first set of methods are actually property definitions (which consist of getter and setter methods):

errormessage: {
get: function () {
  return this._errormessage;
},
set: function (value) {
  this._errormessage = value;
}
},isvalid: {
get: function () {
  return this._isvalid;
},set: function (value) {
  this._isvalid = value;
  this._changeVisibility();
}},

Each of these properties has a get and set method, interacting with the instance variables defined in the constructor.  Even though the define method has separate method calls, we’re constructing one class, and as such, this just works.

In the class definition, the required validator also defines instance methods.  The following method builds the UI via traditional means, and styles it appropriately.  Nothing special here; it really doesn’t have to be.

_buildVisualTree: function () {
var el = this.element;
el.innerHTML = this.text || this.errormessage;
el.style.display = “none”;WinJS.Utilities.addClass(el, “Validator”);
},

Finally, we get to the main highlight of the control, which is the process for validating the content. Our validator first checks that the input of the control has been provided, and our target element has a valid length string.

_getValue: function() {
    var el = document.getElementById(this.targetID);
    var val;

    if (typeof (el.value) !== “undefined”)
        val = el.value;
    else
        val = el.innerHTML;

    return val;
},

validate: function () {
    var val = this._getValue();
   
    this.isvalid = !!val;
    this._changeVisibility();

    this.dispatchEvent(“validated”, { value: val, isValid: this.isvalid });

    return this.isvalid;
}

We have our validator, of which we can define as many as we want on the page. In ASP.NET, a postback to the page, when the control has it’s CausesValidation property set to true, invokes the validation process. Since we don’t have that here, I added one additional class, whose responsibility it is to trigger the validation, which is something we’ll look at in the next post (including it in this post made the post too long).