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 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?

Using Interfaces for ASP.NET MVC Model Binding

Sometimes you may want to support view reuse, where a partial view displays a portion of the application in a reusable fashion. Suppose you had the following entity which has a bunch of properties.

public class Customer
{
   public int CustomerID { get; set; }

   public string FirstName { get; set; }

   public string LastName { get; set; }

   public string AccountNumber { get; set; }

   .
   .
}

Suppose you wanted to use a PartialView because it was an AJAX widget with a JavaScript initialization script, and defining a reusable control made it really easy to support this. MVC defines a strongly typed model reference, so does that mean we have to bind the model directly to Customer, or define a custom type for an editor template?

We actually can use interfaces by adding the following:

public interface IAccountEntity
{
   string AccountNumber { get; set; }
}

We can define this in a partial view:

@model IAccountEntity

@Html.TextBoxFor(i => i.AccountNumber)

   $(function() {
      /* Registration Script */
   });

And then use it in our EditCustomer view, as a partial with the existing model:

@Html.Partial("EditAccountNumber", Model)

Since Model (of type Customer) is also IAccountEntity, this translates just fine with MVC. It works just as well when you use hierarchies too. For instance, Customer implements IAccountEntity, but what if we had a CustomerModel class above Customer like:

CustomerModel
     Customer : IAccountEntity
        AccountNumber

If EditCustomer view looks like the following:

@model CustomerModel
.
.

<div class="form-group">
   <label class="col-md-2 control-label">First Name</label>
   <div class="col-md-10">
       @Html.TextBoxFor(Function(i) i.Customer.FirstName)
   </div>
</div>
<div class="form-group">
   <label class="col-md-2 control-label">Last Name</label>
   <div class="col-md-10">
       @Html.TextBoxFor(Function(i) i.Customer.LastName)
   </div>
</div>
<div class="form-group">
   <label class="col-md-2 control-label">AccountNumber</label>
   <div class="col-md-10">
       @Html.Partial("EditAccountNumber", Model)
   </div>
</div>

Notice how the model is passed in directly; this won’t work for our scenario, because the EditAccountNumber expects an IAccountEntity, and requires that the partial be passed in this way:

@Html.Partial("EditAccountNumber", Model.Customer)

However, that doesn’t work for our needs, if our controller has a post operation of the following:

[HttpPost]
ActionResult Edit(CustomerModel model)
{
    if (string.IsNullOrEmpty(model.AccountNumber))
    {
      //This will always be the case, why?  See below
    }
}

Welcome to one of the challenges of MVC model binding. In the previous form, the first/last name and account number would post back to the server something like:

Customer__FirstName: BOB
Customer__LastName: SMITH
AccountNumber: ABC123

What needs to happen is the “AccountNumber” key also needs to be Customer__AccountNumber for it to successfully bind back to the server. You can add AccountNumber as a parameter to the post method, or we can add another interface that supports our hierarchy, and add this interface to the CustomerModel:

//Interface definition
public interface IAccountNumberModel
{
    IAccountNumberEntity Customer { get; set; }
}

//Update to the model class
public class CustomerModel : IAccountNumberModel
{

   public Customer Customer { get; set; }

   IAccountNumberEntity IAccountNumberModel.Customer { get; set; }

}

Here IAccountNumberModel has the same property name as CustomerModel; that’s important to make sure the model binding name structure matches. Now we can pass in the CustomerModel to the EditAccountNumber view with these modifications:

//EditAccountNumber
@model IAccountNumberModel

@Html.TextBoxFor(i => i.Customer.AccountNumber)
.
.

//EditCustomer:
.
.
@Html.Partial("EditAccountNumber", Model)

Since CustomerModel implements IAccountNumberModel, and this matches the type of model on our partial view, everything binds correctly.

ASP.NET MVC Seamless Routing Encryption

There are certain pages in the application where the data passed in must be encrypted in a GET request. This could be a link redirection from an email or another site, or just an internal redirect where the parameters can’t get exposed. A link like this may actually look like:

/Some/Action?enc=345SFIPOWHG:LNNJE:LKJWET46-DSFSF:KJ

The data is nonsensical to the user, but contains identifying information about the user. For instance, the encrypted data may have the following information:

– User ID
– Response Identifier
– Response (Yes/No, Agree/Disagree, text description, whatever else)

The system can then check that the user logged in matches the user in the URL request. It can lookup the associated response database record, and record the response provided. This feature is not native to ASP.NET MVC, but is relative easy to build in. This post will illustrate how to do so, using the following steps:

1) The first step is to create an action method to define a URL. We’ll want to create two forms: one method as a redirection, and one method as an URL generation. Both of these will be extension methods on different objects:

private static string GetEncryptedData(object args)
{
    var encryption = new EncryptionService();
    var list = new RouteValueDictionary(args);
    var items = new List();

    foreach (var entry in list)
    {
         items.Add(entry.Key + "=" + (!string.IsNullOrEmpty(entry.Value) ? entry.Value : ""));
    }

    return encryption.Encrypt(String.Join("&", items));
}

public static ActionResult RedirectToActionSecure(this ControllerBase controller,
                                                  string action, 
                                                  string controller, 
                                                  object args)
{
    var encText = GetEncryptedData(args);
    return controller.RedirectToAction(action, controller, new { enc = encText });
}

public static IHtmlString ActionSecure(this UrlHelper url, 
                                       string action, 
                                       string controller, 
                                       object args)
{
    var encText = GetEncryptedData(args);
    return url.Action(action, controller, new { enc = encText });
}

Certainly, you can create overloads without the action and/or controller too, which is easy to do. Additionally, this code should do more null checking; it assumes that the data exists. The first step is get a reference to the encryption service you are using for your application. I’m leaving that out of this post. Using this service, a querystring is generated and then encrypted together. The value is stored in the “enc” querystring value when routed. This looks like in the code:

public ActionResult X()
{
   return RedirectToActionSecure("Action", "ctlr", new { a = 1, b = 2 });
}

Or in the view:

@Url.ActionSecure("Action", "ctlr", new { a = 1, b = 2 });

When a request is made to that controller and action, MVC checks for the “enc” querystring parameter. It does this in an Action filter attribute, on ActionExecuting.

public class EncryptionActionAttribute : ActionFilterAttribute
{
   public override void OnActionExecuting(ActionExecutingContext context)
   {
        var encryption = new EncryptionService();

       // Step 1: parse the URL
       var url = context.HttpContext.Request.Url.ToString();
       var index = url.IndexOf("enc=");

       if (index > 0) {
         //Get the encrypted value and decrypt it.
         var encText = context.HttpContext.Server.Decode(url.Substring(index + 4));
         var groups = encryption.Decrypt(encText).Split('&');
         var actionParams = filterContext.ActionDescriptor.GetParameters();

         //Parse all of the "KEY=VALUE" groups
         foreach (var group in groups)
         {
            var pair = group.Split('=');

               if (pair.Value == null)
                 continue;

               //Make sure the action has the parameter of the given name
               var actionParam = actionParams.FirstOrDefault(i => i.Name == pair.Key);
               if (actionParam != null) {
                  var nullType = Nullable.GetUnderlyingType(actionParam.ParameterType);

                  //If a nullable type, make sure to use changetype for that type instead; 
                  //nullable types are not supported
                  if (nullType != null)
                     context.ActionParameters[pair.Key] = 
                          Convert.ChangeType(pair.Value, nullType);
                  //Otherwise, assign and cast the value accordingly
                  else
                     context.ActionParameters[pair.Key] = 
                          Convert.ChangeType(pair.Value, actionParam.ParameterType);

               }

         }
       }
   }
}

There’s a lot to it, so let’s break it down:

– Again, missing null checks and conversion error recovery, so you’ll want to ensure that’s there.
– The first step is to grab the encrypted value from the URL and decode it; once we have this value, the encrypted value is decrypted to get the key/value pairs.
– The filter context has two parameter types: ActionDescription, which GetParameters() returns the metadata of the action method, and ActionParameters, which is a collection of values about to be injected into the action. The ActionParameters collection can be added or modified as you like.
– Each key/value pair is evaluated, and injected into the ActionParameters collection; the values that were encrypted were injected in.
– We first have to check that a nullable type is converted correctly; otherwise, the cast to a nullable type through ChangeType raises an exception.

Some/Action?enc=23442q5wetew

It’s decrypted to:

UserID: 1
ResponseID: 3
Response: YES

The values are inserted into an action method like this:

Entity Framework Table Tricks

I’ve seen out on the web quite a few questions about how to do this or that with Entity Framework, so I’d thought I’d write up a solution to various ways to work with tables and to customize entities.

Sets

Suppose we have a context with a Customers table; by default, the Entity Framework code generator generates code that allows the consumer to do the following.

var ctx = new EFContext();
ctx.Customers.Where(i => ..);

The Customers property is a DBSet object that is responsible for “table management”, which is not quite right but a good quick way to understand it. The DBSet is the primary mechanism for generating queries against the table and adding new objects to the table. Entity Framework code generators create wrappers around this object, but also expose the following methods in two forms:

public System.Data.Entity.DbSet Set(Type type);
public System.Data.Entity.DbSet Set();

Referring to a table generically using the set method comes in handy when you want to simplify your data access code. To explain what I mean, let’s look at a small sample. We may want to use the repository pattern like this:

public interface IRepository
 where T: class
{

    IEnumerable GetAll();

}

public class CustomerRepository : IRepository
{
   public IEnumerable GetAll()
   {
      var ctx = new EFContext();
      return ctx.Customers.ToList();
   }
}

Note how we write the code in each and every repository; we have 1 now, but as the system grows, each repository has to write this same code over and over again. Sure, we can generate it automatically, but we can also do this:

public abstract class BaseRepository : IRepository
{
   public IEnumerable GetAll()
   {
      var ctx = new EFContext();
      return ctx.Set().ToList();
   }
}

public class CustomerRepository : BaseRepository
{

}

Notice the set method usage and how this one common method prevents us from having to write common code. Now we have one method shared across all repositories. We could also use the other override like so:

ctx.Set(typeof(Customer));

Although, it’s far less flexible than the generic form. A lot of the common options are not available out-of-the-box. One important use you can use it to add objects to the database, however.

var customer = new Customer { .. };
ctx.Set(typeof(Customer)).Add(customer);
ctx.Set().Add(customer);

ctx.SaveChanges();

SaveChanges then commits any changed made, raising errors for any validations or update exceptions.

Using Interfaces

Using interfaces can add in some nice flexibility. Suppose we have an interface like this:

public interface IAuditEntity
{
   public DateTime Entered { get; set; }

   public DateTime? Updated { get; set; }
}

Supposing that all of your entities implement this interface, you can simplify your repositories by creating common code:

public abstract class BaseRepository
{

   public IEnumerable GetUpdatedSince(DateTime check)
      where T: IAuditEntity
   {
      var ctx = new EFContext();
      return ctx.Set().Where(i => i.Updated != null && i.Updated.Value > check);
   }

}

While the example above is not the most useful, it illustrates what can be done to create common routines in entity framework. Since Updated matches the name of a field in the table being queried, Entity Framework resolves this correctly; if the name doesn’t match, an exception will be raised saying the property defined in the expression doesn’t exist in the table.

Functions

What floored me though is through a method, Entity Framework can bridge the gap and provide common code. For instance, suppose we had entities like this:

public class Customer
{
   public string Country { get; set; }
}

public class Employee
{
  public string PrimaryCountry { get; set; }
}

We couldn’t create an interface with the name Country, because Employee doesn’t have a matching property. We could change the name, but for the sake of the example, let’s keep them different. Since property name mismatches cause errors, we can surprisingly use functions. An architect had shown me this and I was floored, simply because properties don’t work. But by doing:

public interface ICountry
{
   public string CountryExpression();
}

public class Customer : ICountry
{
   public string Country { get; set; }

   public string CountryExpression()
   {
      return this.Country;
   }
}

public class Employee
{
  public string PrimaryCountry { get; set; }


   public string CountryExpression()
   {
      return this.PrimaryCountry;
   }
}

And then doing the following in the query will work:

public IEnumerable GetByCountry(string country)
 where T: ICountry
{
  var ctx = new EFContext();
  return ctx.Set().Where(i => i.CountryExpression() == country);
}

An architect showed me this trick, and I was floored that it worked since properties don’t. Hopefully this post illustrated some tricks to using entity framework and reduce the overall coding needed.

ASP.NET MVC Dynamic Reference Data Loading

MVC, like any other language, is a tool that has plenty of capabilities when rendering client markup; one method call can render pages of client markup. Using a server-side approach can simplify some of the rendering of content needed. As a for instance, here is one common situation I often use a server-side approach to rendering content within an application. An application may have a Kendo DropDownList, which is highly dependent on a list of some data in JSON format. The initialization script looks like the following:

$("DropDownList").kendoDropDownList({
   dataSource [{ .. }],
   dataTextField: "Text",
   dataValueField: "Value"
});

Typically, the data source is some lookup data source; in most applications, lookup data typically contains a key and value. The dataTextField and dataValueField properties map to values within these It’s helpful to have lookup data that’s standardized, because it’s easy to create a helper function that does the following:

@Helper LookupData(IList data)
{
   return NewtonSoft.JSON.JsonConvert.SerializeObject(data);
}

This helper converts data to JSON, which is used in the script below.

$("DropDownList").kendoDropDownList({
   dataSource @LookupData(Model.CustomerTypes),
   dataTextField: "Text",
   dataValueField: "Value"
});

Here we take a collection of reference items and use that to convert it to JSON. Really, that approach may not be that useful, but where you can find use is if you have a common reference table loader object. Using this, the helper function can automatically retrieve a common dataset based on a given type of reference data:

@Helper LookupData(Type referenceType)
{
    var container = Framework.Container; // this is a singleton reference to the dependency injection container
    var referenceData = container.GetInstance(); //A utility class to load common reference data

    return JSONConvert.DeserializeObject(referenceData.GetValues(referenceType));
}

The reference data uses an IReferenceTableManager class to perform the work. Behind the scenes, this could be anything, including Entity Framework. Below is one possible solution:

public class ReferenceValue
{
    public int ID { get; set; }

    public string Text { get; set; }
}

public interface IReferenceTableManager { 
   IEnumerable GetValues(Type type);
}

public class EFReferenceTableManager : IReferenceTableManager {
  public IEnumerable GetValues(Type type)
  {
     var ctx = new EntityFrameworkContextInstance();

     //From a given type, there are multiple ways to get the data from the DB; I am not
     //aware of a way to query by type (at least easily). There may be a better way to do this,
     // but for the time being, the two possible ways to do query referenced data dynamically
     //by generics are: using reflection or, using a long if statement and type checking like:
     if (type.Equals(typeof(Countries))) {
       return ctx.Set().ToList();
     }
     else if (type.Equals(typeof(States))) {
       return ctx.Set().ToList();
     }
     .
     .
  }

}

Not the best implementation; I’m sure there is something better out there, but you get the idea as to how this dependency can now be implemented dynamically. However, the question most will have is whether this is scope creep on behalf of the view (as to whether this is a responsibility of the controller). It’s also possible to have the lookup helper examine a given model and extract the data from there too. There are multiple ways to solve this problem.

Customizing the MVC Form

MVC has a set of wrappers for generating forms, which is illustrated using the following in C# Razor:

using Html.BeginForm()
{
  @* Form content *@
}

Under the scenes, Html.BeginForm renders a tag for the current controller/action (or custom ones if the parameters are supplied). It does more than that though; it works with a FormContext and generates a unique ID for the form. Being that the Microsoft way is to internalize a lot of their components, it makes it difficult to customize.

It’s actually pretty easy to customize the MVC form using a wrapper. There are several good reasons for doing so. The first reason is standardization. Most forms provide some common header or footer content around their forms to improve the appearance, or to follow a specific CSS framework. The form could also output a ValidationSummary at the top, thus saving the developers from having to write it. I did this similarly with the Anti-forgery tokens so that every form was protected.

The first step to doing so is create a form class:

public class CustomForm : MVCForm
{
    private MvcForm _form = null;
    private ViewContext _viewContext = null;
    private bool _disposed = false;

    public CustomForm(MvcForm form, ViewContext viewContext) : base(viewContext)
    {
       _form = form;
       _viewContext = viewContext;
    }
}

The constructor of the form wraps the MVC form, taking it as the first constructor parameter, and the ViewContext which the form expects. To render the end of the form, override the Dispose method, and do the following:

protected override void Dispose(bool disposing)
{
    if (_disposed)
      return;

     //Wrap up any customization HTML here

     if (_form != null) {
       _form.Dispose();
     }
    _disposed = true;
}

On disposing of the form, this renders the end of the form (the end tag, and wrap up some of the internal form stuff).

The initial rendering of the form happens in the BeginForm extension method, so we need something similar:

[Extension]
public static CustomForm BeginCustomForm(this HtmlHelper html, ..)
{
   var form = html.BeginForm(..); //set parameters to form, let the original form do the work or rendering
   html.ViewContext.Writer.Write(html.AntiForgeryToken());
   html.ViewContext.Writer.Write("I'm within the form, write any customization text here");
}

Here the html.BeginForm extension renders the tag with any attributes provided. It also writes the anti-forgery token and a custom message.

And that’s all it takes to standardize your applications forms and minimize the actual amount of code you have to write! It can amount to a time savings over the long run of an application.

Dynamic Script Registering Component in ASP.NET MVC

One of the performance enhancements recommended in tools like YSlow and others is to put your JavaScript script files at the bottom of the page. The great difficulty in a web forms or MVC web application with doing that is scripts at the bottom of the page are typically added in the master page. Any pages or views can make use of a special section just for scripts, but partial views or user controls can’t take advantage of that.

I’m about to illustrate a solution that will do just that. It’s setup for MVC, but could be easily adapted for web forms by making the helpers as controls. You have to understand that MVC is a top down structure. So as views or partials render, they render their contents in place. The common approach is to have a section for scripts:

site.master:


  // master page common scripts


@* for any custom scripts in the view *@
@RenderSection("scripts", false)

The view can add a @section scripts { } to take advantage of this, but the partial view cannot. Additionally, everything is rendered in top down format; if a partial view at the top of your page has a script like:


$(function() { alert("In the partial view"); });

The problem with this script is that the final rendered view (when scripts are defined at the bottom) will look like:


$(function() { alert("In the partial view"); });


.
.
.
view content
. . // master page common scripts // view scripts

Since it’s top down, it’s also dependent on order, so scripts defined have no dependency (lacking a dependency feature like angular or script JS).

The following solution was meant to give more control over placement of defined scripts. Scripts are defined in a wrapper, and queued up for later rendering. The solution I’m providing is simple, but easily enhanced to add dependencies in scripts, custom ordering, and more features.

To give an idea of what we need to do, the system will achieve something like the following:

view.cshtml:

@Html.AddScript("ViewInit", () => @$(function() { .. }));

partial view:

@Helper Script()
{
   
     ..
   
}

@Html.AddScript("PartialInit", (m) => Script());

master:

@Html.PlaceScripts()

The idea is to add scripts via a method, which queues them up to be rendered, and writes them out at the point the PlaceScripts method is called. Note that for partial views, I’m using a little trick I noted earlier, whereby using a helper is the only way to circumvent exceptions that occur when using the action-based approach.

AddScript essentially adds the definitions to the HttpContext.Items collection, a common trick for storing singleton-like data elements that are available across the application. Since HttpContext.Items is available to add and then render scripts, it’s a great place to share content. The AddScript method shoves in data:

public void AddScript(HtmlHelper html, string key, Action fn)
{
    var http = html.ViewContext.HttpContext;
	var list = http.Items["_Scripts"] as Dictionary;
	
	if (list == null)
		list = new Dictionary();
	
	list[key] = fn;
	
	http.Items["_Scripts"] = list;
}

This method checks to see if we have a dictionary in the items collection; if not, it creates it, pushes in our item, and updates the collection. Similar, our other method, which takes a helper result, uses another overload to store the string result for easy rendering:

public void AddScript(this HtmlHelper html, string key, HelperResult fn)
{
	this.AddScript(html, key, fn(html.ViewData.Model).ToHtmlString());
}

public void AddScript(this HtmlHelper html, string key, string script)
{
    var http = html.ViewContext.HttpContext;
	var list = http.Items["_Scripts"] as Dictionary;
	
	if (list == null)
		list = new Dictionary();
	
	list[key] = script;
	
	http.Items["_Scripts"] = list;
}

We could easily add dependencies and ordering requirements to this solution if we needed; for now, let’s finish this out by showing how to grab the contents and render them:

public void PlaceScripts(this HtmlHelper html)
{
var http = html.ViewContext.HttpContext;
var list = http.Items[“_Scripts”] as Dictionary;

if (list == null)
return;

using writer = new HtmlTextWriter(html.ViewContext.Writer)
{
foreach (var entry in list)
{
if (typeof(entry.Value) is string) {
writer.WriteLine(entry.Value);
}
else {
//This is an action; the action will be
//rendered in the current output stream, and
//do not need to be directly written
entry.Value(html.ViewData.Model);
}
}
}

}

This would need greatly enhanced for dependencies and sorting; right now, we take the list in order and render it out. For HTML results or just plain string definitions, it gets rendered to the current response stream. Actions get processed the same way, but MVC handles that internally, rather than your code.

And voila, we are done; now we can define scripts in the view and partial views and expect them to be rendered where we want them placed, and have a component that can be easily enhanced to do much more.