My Time As a Microsoft MVP

In the early 2000’s, I was working for a State agency in Pennsylvania in a .NET development role.  I’ve always been fascinated by programming on many levels: I really liked to learn the nuts and bolts of the framework, as well as the ability to create something – albeit digitally.  I tried to learn as much as I possibly could; I’d read tech books, read web sites, and post on forums.  I was pretty active specifically on the ASP.NET forums.

Sometime in 2007, I received an email from Microsoft in regards to the MVP program!  I was shocked when I got the email.  I spent a lot of time there, posting questions in hoping to gain insight and trying to provide answers to assist the technical community.  When the honor was confirmed, I was really appreciative of it; it was a great honor.

Fast forward 10 years later:

mvptenyears

I’ve been very blessed individual.  I’ve gotten to offer my time and skills to the community.  I’ve gotten to meet individuals at Code Camps or Give Camps.  I’ve gotten to write for DevProConnection Magazine, ASP Alliance, DotNetSlackers, DotNetJohn,  this blog, and other places.   I considered speaking for Pluralsight, but I’m not the greatest speaker.  Additionally, I’ve gotten to be involved in interesting projects over the years, as I shifted from government work to consulting work to product development.  I’ve gotten to help analyze and solve other people’s technical (and sometimes personal) problems.

Life really comes at you fast some times.  It doesn’t seem like long ago that our 3 children entered our world, but the facts remain the same (ages 11, 9, 7).  We adopted our beautiful daughter from China, and we are in the process of adopting our son (also from China).  My kids have been involved in school plays, baseball games, soccer practices and games, basketball games, holiday events, church activities, school events and more.  As my career progressed, my workload got bigger, my involvements became greater, and my stresses increased.  I burned out a few times along the way, my free time dwindled between work, an ever growing family, and general increased demands.

Ten years was my run as a Microsoft MVP.  I was informed that I will not be renewed.  Microsoft was great to me and gave me many opportunities during that ten years; I am forever grateful for that.

Advertisements

AJAX File Uploads with HTML 5

I see on StackOverflow the question often how to upload a file via AJAX.  It turns out it is actually not that difficult. We utilize a solution using the Html 5 FileReader component. The idea is have the file reader read a PDF file contents, and transfer those contents to a hidden field (stored in the $hidden variable). A portion of the script we use is shown below.

$("#FileUpload").on('change', function (e) {
var $self = this;
var file = $self.files[0];

var fileReader = new FileReader();
fileReader.addEventListener('load', function () {
   var result = fileReader.result;
   $hidden.val(result);
});
fileReader.readAsDataURL(file);

$self.val('');
});

Once a file is read, it invokes the “load” event with the contents of the file; the contents of the file are then stored in a hidden field. Since the contents are in the HTML file, it’s possible then to send those HTML contents to the server, or be a part of a normal postback lifecycle.

The idea with “readAsDataURL” is it creates a URL like the following: “data:text/html,sdafadf34533543sefkafdsadf90809as8dfasdf90asdf9fsdf” where the contents of the PDF are really large. You’ll need to extend what is acceptable as a part of your content.

On the server side, the solution is as simple as splitting the contents after the first comma like:

//Strip off the "data:text/html," portion of the data URL posted back to the server
fileContents.Substring(fileContents.IndexOf(",") + 1);

This is one of many solutions; there are a wide variety of JQuery or other solutions out there.

Watch Your Scoping

I recently found a bug in a plugin and so I figured that would be a good time to offer a public service announcement as to why you have to be careful with scoping in JavaScript.  The plugin I’m featuring is just a quick example of the problem.  Suppose your had the following HTML snippet:


< div id="section1" class="section" >
First Button
< span id="sp1" >0< /span >
< /div >
< div id="section2" class="section" >
Second Button
< span id="sp2" >0< /span >
< /div >
< div id="section3" class="section" >
Third Button
< span id="sp3" >0< /span >
< /div >

Pretty simple. The idea of my plugin was to target the root DIV tag, and then parse down to the BUTTON and SPAN at an individual level. Now, as I think about writing this, the reality is of the situation, I should have considered the JQuery Widget API, as I think that would have been better situated for what I am about to do. I was under the gun to get this feature completed, and this solution was not optimal, but it worked and did get the job done. Anyway, the JQuery plugin is below:

$.fn.parse = function() {
  return this.each(function() {
    var spn = $(this).find("span");
    btn = $(this).find("button");
    
    btn.on("click", function(e) {
       var n = parseFloat(spn.html());
       n += 1;
       spn.html(n);
    
       btn.html(btn.html() + "(clicked)");
    });
  });
}

The idea is that the span and button are retrieved within the context of the root DIV, and when the button is clicked, both elements are updated to indicate that a click occurred. You’ll notice though, that while the span gets the proper update, the button does not (always targets the last). This is simply because the button doesn’t include “var” declaration. This means the button is scoped beyond the current context of the each() callback. Because of this, the last button was selected and thus the last button is represented in the query.

This produces the result:

jsscreenshot

Adding VAR was the immediate solution. Another reminder why you need to make sure you variables are scoped correctly.

Just to brainstorm, another solution could be to, using the current reference within the button click, access the button through the callback and even target the SPAN that way, rather than relying on variables.

You can view the Gist here.

Database T4 Templating Tricks

I love T4 templates. It’s incredible how much canned code can be generated automatically for you. T4 can not only generate static code, but it can do much more like access the database through SMO. All you need to do is define the server and database like so:

<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<#@ assembly name="Microsoft.SqlServer.Smo" #>
<#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>

<#@ import namespace="Microsoft.SqlServer.Management.Smo" #>
lt;#@ import namespace="Microsoft.SqlServer.Management.Common" #>


<#
 var server = new Server("localhost");
 var db = server.Databases["MYDB"];
#%gt;

In this database, suppose you have a Types table that’s static. Your types table may be a ID/Name pairing in the database, which you reference either using magic numbers (the ID since it’s static) or do a Name cross reference. With T4, instead of using numbers or strings, you could hard-code the values by querying the table and creating constants for each type:

public class Constants
{

      public partial class SettingTypes
      {
<#
         var catDS = db.ExecuteWithResults("select ID, Name from dbo.SettingTypes where Visible = 1");
         foreach (DataRow row in catDS.Tables[0].Rows)
         {
#>
         public const long <#= row["Name"].ToString() #> = <#= row["ID"].ToString() #>;
<#
         }
#>
      }
}

Above using the global DB server reference, we use the ExecuteWithResults method to run a specified query against that database, and return the results as a DataSet. The system processes the results and generates “public const long XYZ = 1” where XYZ is the name in the table, and 1 is the ID. We can generate whatever we want; for instance, you could generate just the names as strings by changing the constant to:

public const string <#= row["Name"].ToString() #> = "<#= row["Name"].ToString() #>;

This produces a result similar to the following (using our first example):

public class Constants
{
   public partial class SettingTypes
   {
       public const long AppName = 1;
       public const long URLRedirect = 2;
       .
       .
   }
}

Or as (using our second example):

public class Constants
{
   public partial class SettingTypes
   {
       public const long AppName = "AppName";
       public const long URLRedirect = "URLRedirect";
       .
       .
   }
}

Through our application, we may have had references to “AppName” or “URLRedirect” or whatever common values this type table would have (this is unfortunately a very generic example and I hope you see how it’s applicable). With our new approach, we can do:

Utilities.LookupSettingType(Constants.SettingTypes.AppName);

We now have a compiled-time reference. This helps to provide extra checking for situations where we may remove entries from the SettingsTypes table. Any code references to it would now produce a compile error.

It’s also possible to connect to a database table’s metadata too, to generate the appropriate metadata for that table. The SMO API has table and column objects, used like below that can generate the metadata to a generated class.

public partial class ApplicationDetails
{
<#
         var ncTable = db.Tables["ApplicationDetails"];

         foreach (Column column in ncTable.Columns)
         {
#>
            public const string <#= column.Name #> = "<#= column.Name #>";
<#
         }
#>
}

This would generate a class like the following:

public partial class ApplicationDetails
{
   public string ID = "ID";
   public string Name = "Name";
   public string Description = "Description";
}

Now we can change any static reference to compile time references by referring to the description column as Constants.ApplicationDetails.Description, rather than just “Description”. It’s also possible to pull other metadata in too, such as the data type and more. If you can’t get everything you need, you can try to query the INFORMATION_SCHEMA views to get any additional information.

One useful utility I created with T4 was a generic ReferenceTypes class, where all of my _Types tables are defined in a static class. This processes all of the tables in the database, generating a static reference to the name of a reference table.

public partial class ReferenceTypes
{

<# foreach (Table table in db.Tables) {
            if (table.Name.EndsWith("Types")) {
#>
         public const string <#= table.Name #> = "<#= table.Name #>";
<#
            }
         }
#>

}

Sounds good? I’ve found a lot of good uses for T4 templates; I even use it to generate a starter shell to create stored procedures, application repositories, started controllers and views for MVC, and more. I’ll touch base on that in another blog post but I hope I helped you see how useful T4 is.

There are some things you shouldn’t use it for. You shouldn’t use it for anything you expect to change dynamically. Because it’s generating classes that get compiled with the projects, you can’t change it from live code and expect the changes to be available. Any changes included are defined as of the last compilation of the application. Another thing that you may find out is you will attempt to implement some common task in T4, but T4 turns out to be not a good solution. I’ve run into this a couple of times.

All in all, T4 templates are great to generate common code and can really cut down on writing redundant code, while adding compile-type checking on reference data.

ASP.NET MVC And Client Side Lists with Kendo

In this post, I’m going to illustrate a very simple way to create client-side list-based UI’s in ASP.NET MVC. The idea with this example is to allow the ability to add a bulk number of list items that doesn’t require constantly posting back to add additional items. In this example, we’ll use Kendo UI Core framework templating capabilities, although any templating framework will do.

To start, let’s look at a very simple model:

public  class SystemTestModel
{
   public List Entities { get; set; }
}

public class SystemListEntity
{
   public string Name { get; set; }
   public string Value { get; set; }
   public bool IsDeleted { get; set; }
}

Here we have a View Model that has a list of child items. Very simple. Notice the entity has 2 properties, and an IsDeleted property, which will be illustrated later. For this example, the controller setup is simple; it reads the form posted values and rebuilds the non-deleted ones:

public ActionResult List()
{
   var model = new SystemTestModel { Entities = new List() };
   return View(model);
}

[HttpPost]
public ActionResult List(SystemTestModel model)
{
   //Remove non-deleted records - deleted from  client
   var entities = model.Entities.Where(i => i.IsDeleted == false);

   //Save entities to DB or other work
   //Reload UI
   return View(new SystemTestModel { Entities = entities.ToList() });
}

Within the view, the Name/Value pairs are rendered

<tbody id="Grid" data-last-index="@(Model.Entities.Count - 1)">
   @for (var i = 0; i < Model.Entities.Count; i++) {
     <tr>
         <td>
            <input type="text" name="@Html.NameFor(m => m.Entities[i].Name)" value="@Model.Entities[i].Name" />
            <input type="hidden" name="@Html.NameFor(m => m.Entities[i].IsDeleted)" value="@Model.Entities[i].IsDeleted" />
         </td>
         <td>
            <input type="text" name="@Html.NameFor(m => m.Entities[i].Value)" value="@Model.Entities[i].Value" />
         </td>
      </tr>
   }
</tbody>

Each server-side item is rendered using the collection-based naming syntax that MVC uses to identify collections. The name for a collection-based item looks like the server-side equivalent: Entities[X].[Field] (ie. Entities[0].Name). This is important because our client-side HTML template must do the same thing:


   <tr>
      <td>
          
          <input type="hidden" name="@Html.NameFor(m => m.Entities[-99].IsDeleted)" value="@Boolean.FalseString" />
      </td>
      <td>
          <input type="text" value="#= Value #" name="@Html.NameFor(m => m.Entities[-99].Value)" />
      </td>
   </tr>

Notice in the template the -99; the really neat thing about the NameFor helper is that the expression doesn’t need to be valid; -99 works and literally renders to the HTML as “Entities[-99].Name”. Notice that the script block is the same equivalent above, but will be used to render client-side additional elements. The HTML between the two doesn’t need to be exact, but similar. The view will use this template when the “Add” button is clicked.

What that really means is that the server may have rendered 2 name/value items, and the client can render additional pairs. Our approach is to ensure that we render the pairs in sequential order whether created from server or client, preserving that sequential order.

The view has an add button. The add button triggers the templating capability of kendo. The idea with the template is to get the HTML for the entry and replace the “-99” with the actual index. So if the server-side rendering produced 2 elements (using indexes 0 and 1), the client-side “Add” button generates items starting from index “2” and greater.

$(function () {
   //http://docs.telerik.com/kendo-ui/framework/templates/overview
   $("#NewButton").on("click", function (e) {
      var html = $("#ItemTemplate").html();
      //Get the last index, add 1 because we are adding an item at the new index
      var index = $("#Grid").data("last-index") + 1;
      $("#Grid").data("last-index", index);

      //Replace -99 with the new Index
      html = html.replace(/-99/g, index);

      //Can be used to apply data values from JS
      var template = kendo.template(html);
      var data = {}; //For now, not doing any template binding
      var content = template(data);
            
      $("#Grid").append(content);
   });
});

The first step here is get the templated HTML, and update the current index appropriately. When this UI posts back, the updated index sequence posts back the new items correctly at positions 2 and greater. When the UI reloads, we now have server-side items created from the new index, and new items can be added again.

You may have noticed the IsDeleted property; this can be used to indicate items as deleted. The UI can have a delete button, which can trigger JavaScript that can hide the entire TR tag of the item from view and update the hidden field. When posted back, a permanent delete can happen (purge from the DB if it was originally persisted).

The main goal of this approach is bulk entry of lists without having to postback to add each item, like web forms used to do.

Here is the entire View (assumes JQuery and Kendo scripts included):

@model SystemTestModel

<form action="" method="post">

   <div class="row">
      <div class="col-md-12">

         <table class="table table-bordered table-hover">
            <thead>
               <tr>
                  <th>Name
                  <th>Value
               </tr>
            </thead>
            <tbody id="Grid">
               @for (var i = 0; i < Model.Entities.Length; i++)
               {
                    <tr>
                      <td>
                         <input type="text" name="@Html.NameFor(m => m.Entities[i].Name)" value="@Model.Entities[i].Name" />
                          <input type="hidden" name="@Html.NameFor(m => m.Entities[i].IsDeleted)" value="@Model.Entities[i].IsDeleted" />
                        </td>
                         <td>
                             <input type="text" name="@Html.NameFor(m => m.Entities[i].Value)" value="@Model.Entities[i].Value" />
                           </td>
                          </tr>

               }
            </tbody>
         </table>

      </div>
   

   <div class="row">
      <div class="col-md-12">

         <button type="submit" name="Action" value="SAVE" class="btn btn-primary">
             Save 
         </button>
         <button type="button" name="Action" value="NEW" class="btn btn-default">
             New
         </button>

      </div>
   </div>

</form>

@section scripts {
   
      <script type="text/x-kendo-template">
               <tr>
                    <td>
                        <input type="text" value="#= Name #" name="@Html.NameFor(m => m.Entities[-99].Name)" />
                        <input type="hidden" name="@Html.NameFor(m => m.Entities[-99].IsDeleted)" value="@Boolean.FalseString" />
                    </td>
                     <td>
                        <input type="text" value="#= Value #" name="@Html.NameFor(m => m.Entities[-99].Value)" />
                     </td>
              </tr>
      </script>

<script type="text/javascript">
      $(function () {

         //http://docs.telerik.com/kendo-ui/framework/templates/overview
         $("#NewButton").on("click", function (e) {
            var html = $("#ItemTemplate").html();
            //Get the last index, add 1 because we are adding an item at the new index
            var index = $("#Grid").data("last-index") + 1;
            $("#Grid").data("last-index", index);

            //Replace -99 with the new Index
            html = html.replace(/-99/g, index);

            //Can be used to apply data values from JS
            var template = kendo.template(html);
            var data = {}; //For now, not doing any template binding
            var content = template(data);
            
            $("#Grid").append(content);
         });

      });
   </script>

}

And Controller:

public class SystemListEntity
   {
      public string Name { get; set; }

      public string Value { get; set; }

      public bool IsDeleted { get; set; }

   }


    public class SystemController : BaseController
    {

         public ActionResult List()
         {
            var model = new SystemTestModel { 
                          Entities = new List<SystemListEntity>() };

            return View(model);
         }

         [HttpPost]
         public ActionResult List(SystemTestModel model)
         {
            var entities = model.Entities.Where(i => i.IsDeleted == false);

            //Save entities

            //Reload UI
            return View(new SystemTestModel { Entities = entities.ToList() });
         }
}

Kendo MVVM Sample in ASP.NET MVC

Kendo MVVM is exciting in UI application development framework that binds a JavaScript model to an HTML view. At the core of the MVVM framework is a JavaScript model definition that defines members of the view model that the view will use. For instance, here is a simplified model:

var vm = kendo.observable({ Name: "" });

The idea here is that the model has a Name property that will be bound. The kendo.observable call wraps the model and prepares it for two-way binding in the UI. In our example, this property can be bound to a control like:

<input type="text" name="Name" data-bind="value:Name" />

Our name property in our view model is bound to the textbox, and the data-bind attribute is responsible for wiring everything up. When the textbox value changes, the view model is updated, and vice versa. This is the main benefit of two-way binding. Taking this and looking at a more complicated example, we can use the same approach within ASP.NET MVC. Below is a sample complex example:

var viewModel = kendo.observable({

                     ID: null,
                     ParentItemCategoryTypeID: null,
                     Code: null,
                     Name: null,
                     IsActive: null,
                     Sequence: null,

                     categoriesDataSource: new kendo.data.DataSource({
                           data: @(Html.Raw(JsonConvert.SerializeObject(Model.ItemCategories)))
                     }),

                     onClear: function (e) {
                           this.set("ID", null);
                           this.set("ParentItemCategoryTypeID", null);
                           this.set("Code", null);
                           this.set("Name", null);
                           this.set("IsActive", false);
                           this.set("Sequence", null);
                     },
.
.
});

This view model has 6 properties (ID, Code, Name, etc.); it also has one complex property (a kendo data source that is used to bind to a grid) and an event handler. I’ll come back to the kendo data source later.

At this point, the init method copies the values from the view model (defaulted to null) to input and other HTML elements in the view. In order to link an element to the view model, it requires the data-bind attribute, like the following samples:

<input type="text" class="form-control" data-bind="value:Name" />

Since MVC HTML helpers render out textboxes, we can use TextBox for with the data_ notation. The data_bind attribute renders as data-bind, so we have complete data- attribute support.

@Html.TextBoxFor(i => i.Name, new { @class = "form-control", data_bind = "value:Name" )

Other uses of data-bind attribute can be to wire up click event handlers, bind listviews to kendo data sources, control the visibility of an HTML element, and more.

<button id="ClearFormButton" type="reset" class="btn btn-warning" data-bind="click: onClear">Clear</button>

<tbody id="listview" data-role="listview" data-template="ListItemTemplate" data-selectable="true" data-bind="source:categoriesDataSource, events:{change:onListChange}">

<div data-bind=”visible:showSection”>

The “click” and “events” binding wire up an event handler to a function in the view model, which handles the event. In the event handler, the this pointer refers to the view model, also providing an event argument that gives you access to the underlying control as well. There are many types of other bindings, such as “css”, “visible”, etc. On init, the values from the view model are wired up to each control, and any change within the input control also updates the view model back. The view model has a get/set method to retrieve and use, or update, the view model.

Notice how data-bind for the listview is categoriesDataSource; this is a kendo.data.DataSource object defined on the viewmodel. Interestingly enough, this object takes a URL to a web service or JSON/JavaScript objects. Using Json.NET, the code above (duplicated below) serializes an array into a JavaScript, the following DataSource definition:

categoriesDataSource: new kendo.data.DataSource({
                data: @(Html.Raw(JsonConvert.SerializeObject(Model.ItemCategories)))
        }),

Is rendered as the following:

categoriesDataSource: new kendo.data.DataSource({
                data: [{"ID": 1, "Name": "ABC", ...}]
        }),

What ties the view to the model is the kendo.init method:

kendo.init("body", viewModel);

Now our view is bound to our model, and everything is initialized appropriately.

Adding Security To Html Helpers

I know the new MVC 5 HTML tag attributes for rendering ASP.NET widgets is all the rage, but there are a lot of useful approaches to using the server-side HTML helpers.  One simple extension method we are going to look at is adding control level security.  Often within our applications, we have a means of providing UI security at the control level.  We may, for instance, hide a control if the user doesn’t belong to a certain role.  It’s really simple to add this as an extension to IHtmlString, which is what HTML tag helpers do.  First, let’s look at how this might be used:

@Html.TextBoxFor(i => i.AccountID).IfInRole("ADMIN")

Notice how our textbox has an IsVisible method; this checks if the user is in the ADMIN role, and if so, it does the following:

public static IHtmlString IfInRole(this IHtmlString html, string role)
{
    if (HttpContext.Current == null)
       return html;

    if (HttpContext.Current.User.IsInRole(role);
       return html;
    else
       return new MvcHtmlString("");
}

In this method, if the user doesn’t have permissions, it outputs a blank string instead of the original HTML, thus providing some level of control security. We could use claims to do this, or some other security feature; it really doesn’t matter what is used behind the scenes. Also, we could also provide some default template to use if the control is hidden, as a blank space may not be optimal. This can especially be the case if you are using Twitter Bootstrap, because your form may look like:

Account @Html.TextBoxFor(i => i.AccountID, new { @class = "form-control" })

And thus a wrapper around it like:

@if (Html.IsInRole("Admin")) {
  
..
}

Or using a lambda template might be better. When there is supporting HTML wrapping the HTML Helper, showing or hiding may be a little more complicated depending on your design. I hope you see from this simple example how you can add some security features into your application using the old-school HTML helpers.

Kendo UI Core and DropDownListFor

Kendo UI Core supports data attribute initialization of its widgets. This initialization approach is largely created for it’s MVVM capabilities, but also can be used for server-side approaches too, which in turn can be used with ASP.NET MVC HTML helpers. The setup may be a little different than you are used to.

Please note: Although Telerik has MVC wrappers already created and ready for you to develop with, these come with the licensed version of the product and are not available through the Kendo UI Core license.

To begin, let’s look at how we’d setup the dropdownlist as an HTML widget without and use of the server.

<select id="reasonID" data-role="dropdownlist" data-option-label="-Select Reason-" data-value="">
  <option selected="selected" value="">-Select Reason-
  <option value="1">Entered in Error
  <option value="2">Removed
</select>

In our example, a select element with a pre-defined list of options is wrapped with the kendo dropdownlist widget. It’s initialized via the data-role attribute, indicating it’s a dropdownlist widget. Next, it defines options that the widget supports. Most of the attributes on the widget that you would configure through the JavaScript API can be defined here, but the syntax differs sometimes (for instance, the optionLabel property you would use in JS initialization is data-option-label in data attribute initialization). If you run into an issue, I was able to find what I needed online so far.

Telerik has some documentation on data attribute initialization here.

The dropdownlist widget can use a textbox as the source, and can also wire data up using JSON via local JavaScript API of via AJAX if you like. I’ve stuck with a select because I’m using the MVC DropDownListFor widget, and to get this widget to render the correct content that I needed, I had to use the following configuration:

@Html.DropDownListFor(
      i => i.ReasonTypeID,      
      Model.ReasonTypes, 
      new
      {
           data_role="dropdownlist", 
           data_option_label="-Select Reason-", 
           data_value=(Model.Receiving.ShrinkTransactionTypeID.HasValue ? Model.Receiving.ShrinkTransactionTypeID.Value.ToString() : ""), 
           style="width:100%;" })

Most of this is standard. The third parameter of DropDownListFor provides HTML attributes to the rendered select option. Here we define the role data attribute used for initialization. The next attribute defines the option label, and the data_value attribute defines the selected value, which is interesting. We already define what’s selected via the lambda expression pointing to our model. However, that’s used to render the selected attribute. What I found is that to cover all selection scenarios (including the default “Select Something” item) is to add the value attribute too, which the widget uses to perform the selection. The code above manually checks for null and converts to an empty string if no value present.

In case you didn’t notice, note how the HTML attribute use data_role, particularly the underscore. The convention that MVC uses is underscore (supported by the language), which is converted to a dash during the rendering process.

Customizing the EF Entity Templates

The nice thing about Entity Framework is that anytime you are using one of the entity template generation capabilities, they are pretty easily customizable. This, of course, means that you are NOT using the pure code-first API most likely (however, to an existing database defines a T4 template). In this blog post, we’re going to quickly update the T4 template to change the default rendering:

using System;
using System.Collections.Generic;
    
public partial class State_LKP
{
    public int StateID { get; set; }
    public string StateCode { get; set; }
    public string StateName { get; set; }
}

To add additional information that the application can later use for metadata purposes, such as the following:

using System;
using System.Collections.Generic;
    
public partial class State_LKP
{
    public const string StateID_Name = "StateID";
    public int StateID { get; set; }
    
    public const int StateCode_MAX_LENGTH = 10;		
    public const string StateCode_Name = "StateCode";
    public string StateCode { get; set; }
    
    public const int StateName_MAX_LENGTH = 50;
    public const string StateName_Name = "StateName";
    public string StateName { get; set; }
}

Notice that each column has a constant defining the name, as well as a constant defining it’s max length defined in the database (if a string).

To do this, we need to open up the .tt file that generates each of the entities. In my version, around line 66, we have the following snippet.

var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
    foreach (var edmProperty in simpleProperties)
    {
#>
    <#=codeStringGenerator.Property(edmProperty)#>
<#
    }
}

Notice that this snippet loops through each of the simple properties (the properties defined one for each column) and renders out a definition (note codeStringGenerator is a class defined in the T4 template that defines all of the markup. I didn’t choose to modify that here). To add the name constants and the max length constants, the updated samples were changed to the following code sample. Comments below indicate the changes made.

var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
    //edmProperty of type EdmProperty
    foreach (var edmProperty in simpleProperties)
    {
        //Check max length - if any max length, then write out a constant
	 if(edmProperty.MaxLength.HasValue)
                {
                        #>
 
                        public const int <#= edmProperty.Name #>_MAX_LENGTH = 
                            <#= edmProperty.MaxLength.Value #>;
 
                        <#
                }	


         public const string <#= edmProperty.Name #>_Name = 
               "<#= edmProperty.Name #>";

    <#=codeStringGenerator.Property(edmProperty)#>
    <#
    }
}

Here we add constants to the output of the properties and everything generates great. You may say it would be better to use attributes; that is possible as well, but for that I’d recommend editing the CodeStringGenerator class (in the T4 template) and update the Property method directly instead.

The T4 template is available here: http://pastebin.com/42NiuwDE

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?