title: webgrid sort ipaddress based on numeric representation
body: <p>I'm trying to sort a webgrid table that has IP Addresses displayed in dotted decimal octets by the integer representation of the IP. In asp.net webforms I could set the sort expression to the other column in the database to achieve the proper sorting.</p>
  
  <p>Is there any way to "properly" sort the IP Address column in my webgrid?</p>
  
  <p>I have a model that looks like this:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel.DataAnnotations;
  using System.Net;
  
  namespace pcnweb_mvc3_v1.Models
  {
      public partial class UPS
      {
          public UPS()
          {
              //this.Switches = new List&lt;Switch&gt;();
          }
  
          [Key]
          public int upsRecId { get; set; }
          [Required, StringLength(32)]
          public string Name { get; set; }
          [StringLength(80)]
          public string Description { get; set; }
          [Required, StringLength(32)]
          public string Size { get; set; }
          [StringLength(56)]
          public string Location { get; set; }
          [StringLength(32)]
          public string Level { get; set; }
          [StringLength(16)]
          public string Circuit { get; set; }
          [StringLength(32)]
          public string Power_Feed { get; set; }
  
          [Required]
          [RegularExpression(@"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|DHCP", ErrorMessage = "IP Address must be in the form of four octets 0-255: 255.255.255.255 or DHCP")]
          public string IP_Address {
              get 
              {
                  if (ipOctet1 == null | ipOctet2 == null | ipOctet3 == null | ipOctet4 == null)
                      return "DHCP";
                  return ipOctet1 + "." + ipOctet2 + "." + ipOctet3 + "." + ipOctet4; 
              }
              set 
              {
                  if (value == "DHCP")
                  {
                      ipOctet1 = null;
                      ipOctet2 = null;
                      ipOctet3 = null;
                      ipOctet4 = null;
                      return;
                  }
  
                  //@todo Parseing could throw a number of errors: ArgumentNullException, FormatException, Exception
                  byte[] temp = IPAddress.Parse(value).GetAddressBytes();
                  ipOctet1 = temp[0];
                  ipOctet2 = temp[1];
                  ipOctet3 = temp[2];
                  ipOctet4 = temp[3];
              }
          }
  
          public long ipTotal
          {
              get 
              {
                  //(first octet * 2^24) + (second octet * 2^16) + (third octet * 2^8) + (fourth octet)
                  return (long)Math.Pow(24, 2) * (long)ipOctet1 + (long)Math.Pow(16, 2) * (long)ipOctet2 + (long)Math.Pow(8, 2) * (long)ipOctet3 + (long)ipOctet4;
              }
          }
  
          private Nullable&lt;int&gt; ipOctet1 { get; set; }
          private Nullable&lt;int&gt; ipOctet2 { get; set; }
          private Nullable&lt;int&gt; ipOctet3 { get; set; }
          private Nullable&lt;int&gt; ipOctet4 { get; set; }
  
          //public virtual ICollection&lt;Switch&gt; Switches { get; set; }
      }
  }
  </code></pre>
  
  <p>Here is the webgrid cshtml page:</p>
  
  <pre><code>@model IEnumerable&lt;pcnweb_mvc3_v1.Models.UPS&gt;
  
  @{
      ViewBag.Title = "Index";
  }
  
  &lt;h2&gt;Index&lt;/h2&gt;
  
  &lt;p&gt;
      @Html.ActionLink("Create New", "Create")
  &lt;/p&gt;
  
  @{
      var grid = new WebGrid(Model, defaultSort: "Name", canPage: true, rowsPerPage:25);
  }
  @grid.GetHtml(
      columns: grid.Columns(
          //grid.Column("upsRecId"),
          grid.Column("Name"),
          grid.Column("Description"),
          grid.Column("Size"),
          grid.Column("Location"),
          grid.Column("Level"),
          grid.Column("Circuit"),
          grid.Column("Power_Feed"),
          grid.Column("IP_Address"),
          grid.Column(
          format: (item) =&gt;
          {
              var links = Html.ActionLink("Edit", "Edit", new { id = item.upsRecId }) + " | " +
                          Html.ActionLink("Details", "Details", new { id = item.upsRecId }) + " | " +
                          Html.ActionLink("Delete", "Delete", new { id = item.upsRecId });
  
              return Html.Raw(links);
  
          })
      )
  )
  </code></pre>