Archive for the ‘ASP.NET MVC’ Category

Requiring SSL For ASP.NET MVC Controllers

Tuesday, August 25th, 2009

There are quite a few posts out there about switching to SSL when a user visits specific areas of a website but I figure the more the merrier so here’s yet another one.

My company is in the process of rolling out an ASP.NET MVC site for a client and specific actions and controllers need to have SSL running to ensure that no sensitive information gets out such as passwords and credit cards.  If a user visits the site using http:// I need to switch them to https:// in certain parts of the website.  Fortunately, ASP.NET MVC is quite extensible so it only took about 4-5 minutes to get a simple solution in place. 

The easiest way I know of to switch to SSL for specific controllers or actions is to create an ActionFilterAttribute that handles redirecting them to an https:// address.  Classes that derive from ActionFilterAttribute can be placed immediately above actions or even controllers in cases where the filter needs to apply to all actions in the controller.  For my situation I needed entire controllers to be SSL-enabled so I placed the attribute above the controller class name.

Here’s an example of the simple RequiresSSL attribute class:

using System;
using System.Web;
using System.Web.Mvc;

namespace Helpers
{
    public class RequiresSSL : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpRequestBase req = filterContext.HttpContext.Request;
            HttpResponseBase res = filterContext.HttpContext.Response;

            //Check if we're secure or not and if we're on the local box
            if (!req.IsSecureConnection && !req.IsLocal)
            {
                string url = req.Url.ToString().ToLower().Replace("http:", "https:");
                res.Redirect(url);
            }
            base.OnActionExecuting(filterContext);
        }
    }
}


A couple of people (thanks Jon and Phil) commented that the ToLower() call I had above could cause consequences with QueryString data.  I could take ToString() out but some people may type “HTTP” instead of “http” which would mess up the replace call.  For the current application I’m working on I only have integers being passed around on the QueryString so it didn’t affect me at all but it definitely could affect string data being passed.  The suggestion was to use the UriBuilder class and after thinking it through more I agree.  Here’s a different version of the RequiresSSL class that uses the UriBuilder class.

 

using System;
using System.Web;
using System.Web.Mvc;

namespace Helpers
{
    public class RequiresSSL : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpRequestBase req = filterContext.HttpContext.Request;
            HttpResponseBase res = filterContext.HttpContext.Response;

            //Check if we're secure or not and if we're on the local box
            if (!req.IsSecureConnection && !req.IsLocal)
            {
                var builder = new UriBuilder(req.Url)
                {
                    Scheme = Uri.UriSchemeHttps,
                    Port = 443
                };
                res.Redirect(builder.Uri.ToString());
            }
            base.OnActionExecuting(filterContext);
        }
    }
}


The RequiresSSL attribute can then be placed above the appropriate action or controller:

[HandleError]
[RequiresSSL]
public class AccountController : Controller
{
    ...
}


If you’re running IIS7 and want to get a test SSL certificate setup for testing purposes check out my good friend Rob Bagby’s excellent post on the subject.

Deploying ASP.NET Applications to Medium Trust Servers

Tuesday, June 9th, 2009

99% of the projects my company works on for clients are deployed internally to an enterprise environment managed by a company.  We rarely have to worry about deploying to a shared hosting environment which is nice.  One of the client projects we finished up recently based on ASP.NET MVC, PLINQO and jQuery was deployed to a shared hosting provider for the client and nothing worked initially.  Everything worked locally of course even if we hit the hosting provider’s database from the staging server code base.  It’s never fun to have development or staging working with the same code failing in production.

After researching the error more we thought it related to data access permissions since we were getting null reference errors as collections were converted to lists (data wasn’t being returned from the database).  Finding the root cause of errors in this situation is like finding a needle in a haystack since you can’t attach a debugger, can’t run SQL Profiler or do anything aside from looking at log files, make code changes, FTP the files to the server and see what happens. 

After thinking through it more and running several isolated tests we realized it wasn’t a data access error that we were getting (even though that’s what logs led us to believe).  With a little research I came across the good old <trust> element that can be used in web.config.  It’s not something that I personally have had to use for over 5 years so I completely forgot about it.  By placing the following in web.config you can simulate a medium trust environment:

<system.web>
  <trust level="Medium"/>
</system.web>

Changing the trust level made the staging environment fail with the same error shown on the shared host (which was awesome….rarely am I excited to get an error).  We found out that a PLINQO assembly we were using didn’t allow partially trusted calls so we located the source for that assembly, recompiled it to allow partially trusted callers and everything was fine. 

Bottom Line/Lesson Learned: If you’re deploying to a medium trust hosting environment you’d be wise to set the trust level to Medium up front to save time and energy down the road.

Video: Getting Started with ASP.NET MVC 1.0

Tuesday, May 19th, 2009

I had the opportunity to speak at the Best of Mix 09 Phoenix event with Tim Heuer and Rob Bagby and had a lot of fun hanging out with everyone.  I was the last talk and due to time constraints didn’t get a chance to cover everything I had hoped to cover, but all of the important topics were discussed. 

The projection screen doesn’t show up too well in the video unfortunately, but all of the slides and sample code can be downloaded here for those that may be interested in following along. The talk covers the fundamentals of ASP.NET MVC, discusses some great features the framework offers and describes how jQuery and even Silverlight can be integrated.  The downloadable code samples demonstrate all of the features discussed in the video.

Getting Started with ASP.NET MVC 1.0 

Click here to view in Windows Media Player (right-click and you can save the file)

Logo

For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit http://www.thewahlingroup.com/.

Emulating the UpdatePanel in ASP.NET MVC 1.0 with AjaxHelper

Thursday, May 14th, 2009

I just finished up a client application based on ASP.NET MVC 1.0 and thought I’d blog about some of the things I really liked.  If you didn’t catch my earlier post titled 5 Reasons You Should Take a Closer Look at ASP.NET MVC and are interested in learning more about what the MVC framework offers I’d recommend reading that first.  The client application my company built required a lot of AJAX functionality behind the scenes and I used jQuery along with MVC controller actions to pass JSON data back and forth in many cases.  However, I did take the UpdatePanel type approach in a few cases since it’s quite easy to do and very efficient as far as the data that gets passed back and forth between the client and server.

ASP.NET MVC 1.0 provides an AjaxHelper class that exposes a BeginForm() method.  HTML controls wrapped in the BeginForm() area are automatically AJAX enabled much like the ASP.NET UpdatePanel.  However, because ASP.NET MVC doesn’t use ViewState or ControlState at all, the calls back to the server are much more efficient when compared to the UpdatePanel (you can use a tool such as Fiddler to verify this:  http://www.fiddlertool.com).  Here are the basic steps to AJAX-enable sections of a view in ASP.NET MVC.

1. Add Ajax.BeginForm into your View

<% using (Ajax.BeginForm("EditCustomerProfile", null,
   new AjaxOptions { UpdateTargetId = "CustomerForm", OnSuccess = "onEditCustomerProfileSuccess" },
   new { id = "EditCustomerProfileForm" }))
   {
%>

<% } %>


BeginForm() has 11 different overloads that can be used.  This example creates an AJAX-enabled section using the AjaxHelper’s BeingForm() method and defines that a controller action named EditCustomerProfile will be called to retrieve the data.  Any route data that needs to be passed can be specified in the second parameter.  The third parameter represents the AjaxOptions that will be used as the client and server interact.  In this case I specify that a control with an ID of CustomerForm will be updated with the data returned from the server.  I also call a JavaScript success callback named onEditCustomerProfileSuccess to perform other necessary actions in the application if the AJAX call returns successfully:

function onEditOfficeProfileSuccess(content)
{
    if ($('#OfficeProfileValSummary').length == 0) //No validation control found so OK
    {
        ClearOfficeProfileControls();
    }
    GetOfficeProfiles();
}

The final parameter represents properties that are added to the form tag generated by BeginForm().  I simply assign the id of the form tag to EditCustomerProfileForm which is done to make it easier to filter controls using jQuery selectors elsewhere in the application.

2. Add the UpdateTargetID div

Once BeginForm() is defined you need to specify the object (div, span or other object) that will receive updates from the server as AJAX calls are made.  In my case I want an end user to complete a form, submit it to the server, validate it, perform business rules there, etc. and then return the form back to the client with a status message about the action.  The form is defined in a user control which is embedded within my ASP.NET MVC view using the HtmlHelper’s RenderPartial() method.  Since the form area gets updated after the call I wrap it with a div that has an ID of CustomerForm (the UpdateTargetID shown above).  Here’s the completed code:

<% using (Ajax.BeginForm("EditCustomerProfile", null,
   new AjaxOptions { UpdateTargetId = "CustomerForm", OnSuccess = "onEditCustomerProfileSuccess" },
   new { id = "EditCustomerProfileForm" }))
   {
%>
    <div id="CustomerForm">
        <% Html.RenderPartial("EditCustomerForm",Model.CustomerViewModel); %>
    </div>
<% } %>


When user submits the form and data returns from the server the CustomerForm div will automatically be updated without having to write any JavaScript code….just like the ASP.NET Web Forms UpdatePanel. The code for the controller action named EditCustomerProfile is shown next.  If everything validates properly it returns the EditCustomerForm user control with a message letting the client know that everything worked.  If errors are found they are added into the model’s error collection and displayed in the form.

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditCustomerProfile(Customer customer, string email)
{
    string emailMessage = null;
    try
    {
        //#### Handle Email
        if (!String.IsNullOrEmpty(email) && Regex.IsMatch(email, @"^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$"))
        {
            emailMessage = UpdateEmailAddress(email);
        }
        else //Email address is null or doesn't follow the RegEx pattern
        {
            emailMessage = "Please check that you entered your email address properly.";
        }

        //#### Handle updating Customer object data
        if (emailMessage == null && customer.IsCustomerValid)
        {
            OperationStatus opStatus = _CustomerRepository.Update(customer,
                c => c.CustomerID == customer.CustomerID);
            if (opStatus.Status)
            {
                ViewData["Status"] = "true";
                return View("EditCustomerForm",
                    new CustomerViewModel(_CustomerRepository.Get(c => c.CustomerID == customer.CustomerID), 
                        "Navy", "Your profile information was saved."));
            }
        }
    }
    catch (Exception exp)
    {
        Logger.Log("Error in AccountController.EditCustomerProfile", exp);
    }
    ViewData["Status"] = "false";
    List<RuleViolation> violations = customer.GetRuleViolations().ToList();
    if (emailMessage != null) violations.Add(new RuleViolation("Email", emailMessage));
    ModelState.AddModelErrors(violations);
    return View("EditCustomerForm", new CustomerViewModel(_CustomerRepository.Get(c => c.CustomerID == customer.CustomerID), 
        "Red", "There was a problem updating your profile."));
}

Adding UpdatePanel-like functionality into ASP.NET MVC applications is a snap and allows you to speed-up end user interaction with pages.  I personally like the fact that successful AJAX calls can easily be routed to callbacks without having to worry about wiring up any helper JavaScript objects.

 


Logo


For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit http://www.thewahlingroup.com/.

Minimize Code by Using jQuery and Data Templates

Friday, April 17th, 2009

I’m currently working on a heavily AJAX-oriented ASP.NET MVC web application for a business client and using jQuery to call controller actions, retrieve JSON data and then manipulate the DOM to display the data. Several of the pages have quite a bit of dynamic HTML that has to be generated once a JSON object is returned from an MVC controller action which generally leads to a lot of custom JavaScript.  After working through my first page on the project I realized that I was creating a maintenance nightmare due to the amount of JavaScript being written and decided to look into other options.

The first thing I looked for was some type of JavaScript template that would work much like GridView templates in ASP.NET.  I wanted to be able to define a template in HTML and then bind a JSON object against it.  That way I could easily tweak the template without having to actually touch my JavaScript code much.  I found several potential template solutions (and Microsoft will be releasing a nice option with ASP.NET 4.0 as well) that were nice but many were so CSS class centric that they ended up being a turn off since I felt like I had to learn yet another coding style just to use them.  I eventually came across one by John Resig (creator of jQuery and overall JavaScript genius) that was so small that I wasn’t sure it would even be viable.  I mean we’re talking tiny as far as code goes…so tiny that I figured it wouldn’t work well for what I needed.  After doing more searching and research I came across a post by my world famous buddy Rick Strahl (if you don’t currently follow his blog you won’t find a better one out there IMHO) that mentioned John’s micro template technique and had a few tweaks in it.  I tried it and was instantly hooked because it gave me the power to use templates yet still embed JavaScript to perform basic presentation logic (loops, conditionals, etc.) as needed.

The Template Engine (chipmunk power)

So here’s how the template works.  The first thing I did was add the template function as a jQuery extension so that I could get to it using familiar jQuery syntax.  This isn't required at all, it’s just something I wanted to do.  I ended up going with Rick’s slightly tweaked version and I only changed how the error was reported.  I’m not going to go into how to extend jQuery in this post, but here’s what the extension function looks like:

$.fn.parseTemplate = function(data)
{
    var str = (this).html();
    var _tmplCache = {}
    var err = "";
    try
    {
        var func = _tmplCache[str];
        if (!func)
        {
            var strFunc =
            "var p=[],print=function(){p.push.apply(p,arguments);};" +
                        "with(obj){p.push('" +
            str.replace(/[\r\t\n]/g, " ")
               .replace(/'(?=[^#]*#>)/g, "\t")
               .split("'").join("\\'")
               .split("\t").join("'")
               .replace(/<#=(.+?)#>/g, "',$1,'")
               .split("<#").join("');")
               .split("#>").join("p.push('")
               + "');}return p.join('');";

            //alert(strFunc);
            func = new Function("obj", strFunc);
            _tmplCache[str] = func;
        }
        return func(data);
    } catch (e) { err = e.message; }
    return "< # ERROR: " + err.toString() + " # >";
}

That’s all the code for the template engine.  Unbelievable really…runs on chipmunk power.

Creating a Template

Once the extension function was ready I had to create a template in my MVC view (note that this works fine in any web application, not just ASP.NET MVC) that described how the JSON data should be presented.  Templates are placed inside of a script tag as shown next (I chopped out most of the template to keep it more concise). 

<script id="MenuSummaryTemplate" type="text/html">
     <table style="width:100%;">
        <tbody>             
            <tr>
                <td class="OrderHeader">Totals:</td>                    
            </tr>                    
            <tr>
                <td style="font-size:12pt;">
                    <table style="width:400px;">
                        <tr>
                            <td style="width:50%;">Sub Total:</td>
                            <td>$<span id="FinalSubTotal"><#= FinalSubTotal #></span></td>
                        </tr>
                        <tr>
                            <td>Sales Tax:</td>
                            <td>$<span id="FinalSalesTax"><#= FinalSalesTax #></span></td>
                        </tr>
                        <# if (DeliveryFee > 0) { #>
                        <tr>
                            <td>Delivery Fee:</td>
                            <td>$<span id="DeliveryFee"><#= DeliveryFee #></span></td>
                        </tr>
                        <# } #>
                        <tr>
                            <td>Admin Fee:</td>
                            <td>$<span id="AdminFee"><#= AdminFee #></span></td>
                        </tr>                                
                        <tr style="border-top:1px solid black;">
                            <td>Total:</td>
                            <td>$<span id="FinalTotal"><#= FinalTotal #></span></td>
                        </tr>   
                        <tr>
                            <td colspan="2">&nbsp;</td>
                        </tr>
                        <tr>
                            <td colspan="2">Will be charged to your credit card ending with <#= CreditCard #></td>
                        </tr>                     
                    </table>                        
                </td>
            </tr>
<!-- More of the template would follow --> </tbody> </table> </script>

You can see that the script block template container has a type of text/html and that the template uses <#=  #> blocks to define placeholders for JSON properties that are bound to the template. The text/html type is a trick to hide the template from the browser and I suspect some may not like that…you’re call though…I’m just showing one option.  The template supports embedding JavaScript logic into it which is one of my favorite features. 

After a little thought you may wonder why I didn’t simply update the spans and divs using simple JavaScript and avoid the template completely.  By using a template my coding is cut-down to 2 lines of JavaScript code once the JSON object is created (which you’ll see in a moment) and this is only part of the template. Here’s another section of it that handles looping through menu items and creating rows:

 

<#
   if (MainItems == null || MainItems.length == 0)
   {
#>
    <tr>
        <td>No items selected</td>
    </tr>
<#
   }
   else
   {
       for(var i=0; i < MainItems.length; i++)     
       {      
         var mmi = MainItems[i]; 
#>
        <tr>
           <td>
                <#= mmi.Name #>:  <#= mmi.NumberOfPeople #> ordered at $<#= mmi.PricePerPerson #> per person
           </td>
        </tr>
<# 
       }
   } 
#>


Binding Data To a Template

To bind JSON data to the template I can call my jQuery extension named parseTemplate(), get back the final HTML as a string and then add that into the DOM.  Here’s an example of binding to the template shown above.  I went ahead and left the JSON data that’s being bound in so that you could see it, but jump to the bottom of LoadApprovalDiv() to see where I bind the JSON object to the template….it’s only 2 lines of code.

function LoadApprovalDiv()
{
    var subTotal = parseFloat($('#SubTotal').text());
    var salesTaxRate = parseFloat($('#SalesTaxRate').val()) / 100;
    var salesTaxAmount = subTotal * salesTaxRate;
    var deliveryFee = parseFloat($('#DeliveryFee').val());
    var adminFee = (subTotal + salesTaxAmount + deliveryFee) * .05;
    var total = subTotal + salesTaxAmount + deliveryFee + adminFee;
    var deliveryAddress = $('#Delivery_Street').val() + ' ' + $('#Delivery_City').val() +
                          " " + $('#Delivery_StateID option:selected').text() + ' ' + $('#Delivery_Zip').val();
    var creditCard = $('#Payment_CreditCardNumber').val();
    var abbrCreditCard = '*' + creditCard.substring(creditCard.length - 5);

    var json = {
                   'FinalSubTotal'  : subTotal.toFixed(2),
                   'FinalSalesTax'  : salesTaxAmount.toFixed(2),
                   'FinalTotal'     : total.toFixed(2),
                   'DeliveryFee'    : deliveryFee.toFixed(2),
                   'AdminFee'       : adminFee.toFixed(2),
                   'DeliveryName'   : $('#Delivery_Name').val(),
                   'DeliveryAddress': deliveryAddress,
                   'CreditCard'     : abbrCreditCard,
                   'DeliveryDate'   : $('#Delivery_DeliveryDate').val(),
                   'DeliveryTime'   : $('#Delivery_DeliveryTime option:selected').text(),
                   'MainItems'      : GenerateJson('Main'),
                   'SideItems'      : GenerateJson('Side'),
                   'DesertItems'    : GenerateJson('Desert'),
                   'DrinkItems'     : GenerateJson('Drink')
               };

       var s = $('#MenuSummaryTemplate').parseTemplate(json);
       $('#MenuSummaryOutput').html(s);
}


You can see that I call parseTemplate(), pass in the template to use and JSON object and then get back a string.  I then add the string into a div with an ID of MenuSummaryOutput using jQuery.  Here’s a sample of what the template generates:


 image


Going this route cut down my JavaScript code by at least 75% over what I had originally and makes it really easy to maintain.  If I need to add a new CSS style or modify how things are presented I can simply change the template and avoid writing custom JavaScript code.  By using the template and AJAX calls I’ve been able to significantly minimize the amount of server code being written and meet the client’s requirement of having an extremely fast and snappy end user experience.  If you’re writing a lot of custom JavaScript currently to generate DOM objects I’d highly recommend looking into this template or some of the other template solutions out there.  I can’t say I’ve tested performance but can say that I’m working with some fairly large templates which are loading in < 1 second.  I personally feel it’s the way to go especially if you want to minimize code and simplify maintenance.  I think Microsoft’s entry into this area with ASP.NET 4.0 further validates the usefulness of client-side templates.

 

Logo

For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit http://www.thewahlingroup.com/.