Atlantic Business Technologies, Inc.

Category: .NET

  • Using .NET 3.5 and Reflection to help with sorting a List

    The other day I was looking to be able to sort a list of products (List<Product>).  I was binding that list to a ListView and the client wanted to be able to sort the Products by Name (Z-A & A-Z) and by Price (Low-High and High-Low).

    I initially had something like this:

    public class SortProductsByPrice : IComparer
    {
      public int Compare(Product Prod1, Product Prod2)
      {
        return Prod1.Price.CompareTo(Prod2.Price);
      }
    }

    That works, but I didn’t want to write a class for everything I wanted to be able to sort by. For what the client wanted above I would have had to write 4 different classes.

    So I set off looking for an awesome way to write one sort method. Sparing you the endless results of clicking through many search results and articles, I ran across a couple things caught my attention: .Net Reflection, hey look I can see myself! and How to sort a ListView control by a column in Visual C#.

    Combining ideas from both of those examples above I produced a class that will Sort a List of any objects.

    public class Sort : IComparer
    {
      // Specifies the Property to be sorted
      public String SortBy { get; set; }
    
      // Specifies the order in which to sort (i.e. 'Ascending').
      public SortDirection OrderOfSort { get; set; }
    
      public Sort(String SortBy, SortDirection OrderOfSort)
      {
        this.SortBy = SortBy;
        this.OrderOfSort = OrderOfSort;
      }
    
      public int Compare(T x, T y)
      {
        int compareResult;
    
        Type MyTypeObject = typeof(T);
    
        PropertyInfo prop = MyTypeObject.GetProperty(SortBy);
    
        if (prop == null)
        {
          return 0;
        }
    
        switch (prop.PropertyType.Name)
        {
          case "String":
            compareResult = prop.GetValue(x, null).ToString().CompareTo(
              prop.GetValue(y, null).ToString());
            break;
          case "DateTime":
            compareResult = Convert.ToDateTime(prop.GetValue(x, null)).CompareTo(
              Convert.ToDateTime(prop.GetValue(y, null)));
            break;
          case "Double":
            compareResult = Convert.ToDouble(prop.GetValue(x, null)).CompareTo(
              Convert.ToDouble(prop.GetValue(y, null)));
            break;
          default:
            compareResult = 0;
            break;
        }
    
        switch (OrderOfSort)
        {
          case SortDirection.Ascending:
            return compareResult;
          case SortDirection.Descending:
            return (-compareResult);
          default:
            return 0;
        }
      }
    }

    Now I can utilize this awesome new class by calling it like this:

    ProductList.Sort("Price", SortDirection.Ascending);

    The concept here is you just pass the property you want to sort by (i.e. Price) and the direction and “Bam” (as Emeril says)!

    The next step here would just be to add some additional cases to my switch statement to check for other DataTypes (like Decimal, Int, etc).

  • Updating a .NET Page in Real-Time Using jQuery and AJAX

    Here’s a problem I bet you’ve run into before. You have a long-running function on one of your .NET pages and you want to provide real-time feedback to the user while they’re waiting on the function to complete (by function, I mean a method or a set of methods in the code-behind). So you put a variable somewhere on your page and you update it as the function runs. Then you realize that the variable value won’t actually change on the front-end until the postback is complete, which in turn means that it will get updated only once and say “Finished.” Just in time to tell the user what they already know.

    To get around this conundrum, I present to you jquery and ajax, my two favorite web technologies ever. AJAX is a group of technologies that allows you to interact with the server from the client-side without affecting the behavior of the existing page. What this means is that you can post to a page without getting the associated postback from .NET (and subsequent page refresh). If that doesn’t sound important, trust me, it is. If we can post to a page without getting a postback, then we’re already pretty close to real-time updates. All we need to do now is use jQuery to update the DOM as we do posts. Sound complicated? It isn’t.

    Back to our example, suppose a user clicks a button and that button fires a postback and runs 3 methods in the code-behind, DoStep1(), DoStep2(), and DoStep3(). The first thing we need to do is simply move these methods to a new page. If your original page was called DoWork.aspx, then a good name for the new page would be DoWork_Ajax.aspx.

    Now, back on DoWork.aspx, you probably have an asp element on your page that you’d like to update as the functions progress. You can replace this with a standard HTML element. DoWork() is a javascript function that will update this element. It looks like this:

    function DoWork(step)
    {
        if (step == 1)
        {
            $("#update-msg").html("Starting Work");
        }
    
        if (step == 4)
        {
            $("#update-msg").html("Finished");
            return false;
        }        
    
        $("#update-msg").load(
            "DoWork_Ajax.aspx #results span", 
            { workStep: step }, 
            function(){ DoWork(step + 1); } 
        ); 
    }
    

    Assume that #update-message is a span on our page, i.e. a placeholder for the status of our worker functions.

    The logic flows as such: If we’re on step 1, tell the user we’re starting. If we make it past step 3, we’re done, so tell the user that too and return from this function. Finally, the meat of the function – Do an asyncronous post to DoWork_Ajax.aspx, telling it what step we’re on, and injecting a span from it into the DOM for the current page.

    The PageLoad method for DoWork_Ajax.aspx looks like this:

    switch (Request["workStep"])
    {
        case "1":
            DoStep1();
            break;
        case "2":
            DoStep2();
            break;
        case "3":
            DoStep3();
            break;
    }
    

    Each method updates an element on the page, just like before. This is the element that gets injected into the DOM by our jQuery function on DoWork.aspx.

    You’re doing the exact same work as before, but now you can update the page in real time. I’ve included a sample application that demonstrates everything I’ve talked about. For those that are interested, you can download the project and run it locally to see this in action.

  • Dynamic Body ID and Class properties on ASP.NET Master Pages

    Master pages are a great feature of ASP.NET. However, they do have some drawbacks, one being they do not easily offer the flexibility of dynamic body ids and classes that our design team here needs.

    Luckily a solution exists, and best of all it isn’t all that difficult to implement. The solution is built around the idea that child pages can access their master page, as well as any publicly exposed properties on the master. For example, in the Page_Load method of a child page, you can write:

    MyMasterPage masterPage = Master as MyMasterPage; masterPage.Property = “property value”;

    This is not ideal though, because we are now committed to never changing our child’s master page; if we do, it will break our build. The correct implementation of this concept is to create an interface that all of our master pages will implement, then use that in our child pages’ Page_Load method:

    IMasterPage masterPage = Master as IMasterPage; masterPage.Property = “property value”;

    We can still set our property this way, only now we can later change what master page we use, as long as the new one still implements the same interface. Good stuff. So good, that it puts us most of the way there towards dynamic body ids and classes.

    To get these, we need a couple of properties on our interface:

    public interface IMasterPage { String BodyId { get; set; } String BodyClass { get; set; } }

    Then, in the code-behind file for our actual master page:

    public partial class MasterPagesDefault : MasterPage, IMasterPage { private string _bodyId; private string _bodyClass; public string BodyId { get { return _bodyId; } set { _bodyId = value; } } public string BodyClass { get { return _bodyClass; } set { _bodyClass = value;} } }

    Finally, in the master page’s body tag:

    <body id=”<%= BodyId %>” class=”<%= BodyClass %>”>

    Now, to set these dynamically, use the child page’s Page_Load method just like before:

    IMasterPage masterPage = Master as IMasterPage; if (masterPage != null) { masterPage.BodyId = “index”; masterPage.BodyClass = “index two-col”; }

    By using publicly accessible properties, we give child pages the ability to set values on their master page. With this, it is easy to create dynamic body classes and ids in .NET.

  • .NET Online Payment Gateways: A Factory Pattern Model

    One thing that any good development company should do is strive to create reusable code.  Thinking back to projects I’ve worked on in my first year here, it occurred to me that quite a few of them have involved some form of online payment processing.  However, each client has used a different payment processor that has required custom programming.  I began thinking how nice it would be to submit a generic payment object to a gateway with large disregard to what particular vendor the payment is being submitted to.   Early on in developing this, it occurred to me that a factory pattern would be the way to go; essentially what I want is a “factory” that will figure out what type of online payment gateway I need and construct that for me.

    To start things, I made a simple payment .NET gateway interface to make sure my gateway objects will do the one thing I need them to:


    public interface IPaymentGateway
    {
    string SubmitPayment(Payment payment);
    }

    Essentially what I’m saying here is that no matter what type of gateway I’m using, I’ll need to submit a payment.

    Next, we have a simple factory pattern to return some type of gateway:

    public class PaymentGatewayFactory
    {
    public IPaymentGateway CreatePaymentGateway()
    {
    PaymentGatewayRepository paymentGatewayRepository = new PaymentGatewayRepository();
    string gatewayType = paymentGatewayRepository.GetGatewayType();

    switch(gatewayType)
    {
    case “Authnet”:
    return new Authnet();
    case “Paypal”:
    return new Paypal();
    case “Payflow”:
    return new PayflowPro();
    default:
    throw new NotSupportedException(“This payment gateway is not supported.”);
    }
    }
    }

    Here we have a call to a PaymentGatewayRepository class (not included), which will read a config file and return a string representing what type of payment gateway the client is using. Next, a simple switch is done that will return the appropriate payment gateway class (or a custom exception if the gateway is not yet supported). Each of the gateway classes implements the IPaymentGateway interface.

    The beauty of this is that once this project is built, submitting payments is a breeze. Just include the assembly in a project, reference it, and then follow these three easy steps:

    1. Add the necessary config keys.<!-- Gateway types | Possible Values: Authnet, Paypal, Payflow -->
      <add key="GatewayType" value="Authnet">
      <!– Authnet Keys –>
      <add key=”Anet_URL” value=”http://test.authorize.net/gateway/transact.dll”/>
      <add key=”payment_login_key” value=”123456789″/>
      <add key=”payment_tran_key” value=”987654321″/>
      <add key=”payment_auth_name” value=”Example”/>
    2. Build the payment object.Payment payment = new Payment();
      payment.BillingFirstName = "Jeremy";
      payment.BillingLastName = "Wiggins";
      etc…
    3. Submit the payment.IPaymentGateway gateway = new PaymentGatewayFactory().CreatePaymentGateway();
      gateway.SubmitPayment(payment);

    And that’s all there is to it. This will be a nice addition to a reusable component library. Once the logic has been implemented for a new payment gateway, it never has to be thought about again. Just add a few lines to a config file and submit payments in a couple of easy steps.