LA.NET [EN]

ASP.NETArchive

Feb 06

Yesterday, we’ve seen how we can handle authorization with the AuthorizeAttribute and how it integrates with the MVC pipeline and with the ASP.NET authentication infrastructure. Today we’re going to keep looking at existing filters and we’ll see how we can use the HandleErrorAttribute for handling exceptions that be raised during the handling of a MVC request.

The HandleErrorAttribute expands the FilterAttribute class and implements the IExceptionfilter interface. This is a really simple interface with only one method:

public interface IExceptionFilter {
       void OnException(ExceptionContext filterContext);
}

As you can guess, this the method that  will be called whenever you have a non-treated exception in an action method. The HandleErrorAttribute implements this method and performs several interesting steps:

  • the first thing it does is check if the current exception has already been handled (probably by some  other filter that has been invoked before) or if custom errors are disabled for the current ASP.NET app (by checking the value of the IsCustomErrorEnabled property of the current ASP.NET context). If any of these is true, then the current filter won’t do anything;
  • after that, it needs to check the “type” of the current exception. If it’s a valid HTTP exception, it won’t do anything (in practice, if the current exception is not convertible to an HttpException with code 500 code, then the filter will simply return);
  • Besides checking the code, it will also see if you have set up the ExceptionType property. You can pass any derived Exception type to this property. Doing that means that the current exception filter will only run for exceptions derived from that type (this  lets you handle only some exceptions or have different views for different exception types);
  • only after doing all those checks will the filter do its “real” work: create a valid ViewResult from its ViewName and MasterName properties and pass that information to the Result property of the ExceptionContext that is passed into the OnException method. It will also change the value of the ExceptionHandled property (which is set to true) and change the status code of the response to 500.

To complete the analysis we still need to answer one question: when are these filters used? If you’ve read this series, then you know that they can only be used from within the ControllerActionInvoker class. What happens is that the InvokeAction method wraps the call to the current action method (which also involves executing authorization filters, action filters and result filters) in a try/catch block. Whenever an exception is triggered (and that exception is not a ThreadAbortException, which should only be triggered by a Response.Redirect call on a web app),it will be caught by that catch block and all the exceptions filters will be give an chance to run.

Even though this post has looked at exception filters,it’s also important to mention  that you don’t need to use this attribute to handle an exception. If  you want, you can also override the OnException method that you inherit from the abstract Controller class. As you’ve seen in the past, the ControllerInvokerAction class will also invoke those methods.

Before ending, there’s still time for an example of how you can use the HandleErrorAttribute. Here’s a snippet that shows how you can redirect the processing of the request to the PrintErrorView of the current controller when you  have and exception of type MyCustomException:

[
    HandleError(
            ExceptionType = typeof(MyCustomException),
            View = "PrintErrorView ")
]
public class HomeController : Controller {
//more code

Notice that you can also specify a master view page by setting the Master property of the HandleErrorAttribute class.

And that’s all for today. Keep tuned for more on the MVC framework.

Feb 06

The MVC framework: wrapping up authorization

Posted in ASP.NET, MVC       Comments Off on The MVC framework: wrapping up authorization

In the last post we’ve seen how we can use the AuthorizeAttribute for authorizing a specific request. At the time, I’ve forgot to mention one detail regarding authorization. Besides using the AuthorizeAttribute or creating your own custom attribute for deciding who can access a specific action method, you can also create your custom authentication code by overriding the OnAuthorization method that your controller inherits from ControllerBase. This might be a good option when you want to reuse you authorization code through several controllers and their action methods.

Feb 05

The MVC platform: integrating authentication and authorization in your apps

Posted in ASP.NET, MVC       Comments Off on The MVC platform: integrating authentication and authorization in your apps

Today we’ll keep looking at the MVC framework and will see how the you can integrate authentication and authorization in your MVC applications. As we all know, authorization and authentication are different things, but they’re “connected”. I say this because whenever you need to decide if a user can execute a specific operation (ie, whenever you think in authorization), the first thing you need to ensure is that you “know” who the current user is (ie, you have already authenticated the user).

The traditional ASP.NET engine already has some infrastructure in place for performing these operations, but you can’t really reuse the same approaches with MVC. To understand why, you just need to remember that in web forms, you access pages and those are the resources that are protected. With MVC, you’re accessing controller’s actions  and that is what you need to protect.

Despite these differences, you can still reuse the available web forms authentication framework based on the “old” FormAuthentication class for authenticating a user and making that info available for future requests. In fact, if you look at the default code generated by the MVC template,you’ll notice that it already is using that class for authenticating a user.

Ok,now we’re ready to go into authorization. In MVC, you can apply authorization to an action based on username or on group. If you don’t pass any information for those options, then it will only let authenticated users access the protected resource (independent of the its username or associated groups). You use attributes (based on filters) to specify this info, more specifically, instances of AuthorizeAttribute class. If you don’t recall how filters work, probably now is a good time to refresh your memory.

Internally, the class will get the IPrincipal for the user from the current context (recall that MVC apps work over some abstractions which end up delegating to the traditional ASP.NET web forms classes) and then it will see if the user is on the list of users defined and/or if the user belongs to any of the roles passed to the attribute. Here’s an example of how you can use this attribute and apply it to an action:

[Authorize(Users = "luis, john", Roles = "group1, group2")]
public ActionResult Index()
{
   //more code

with the previous snippet, you’ll have to be authenticated as luis or john and you must also belong to group1 or group2 in order to execute the Index action (do notice that if you specify both options, then the current  user needs to satisfy both of them).

Before ending, there’s still time  to mention an interesting detail: in order to guarantee that the action is only executed by authorized users, the class ends up hooking the validation callback performed by the cache. This is an important detail because cache checking is performed before the code on the controller is run and if this hook wasn’t set up, then it would be possible for a non authorized user to get a page that was recently viewed by another authorized user.

And that’s all for today. Keep tuned for more on the MVC framework.

Feb 04

The MVC platform: interacting with the ActionMethodSelectorAttributes

Posted in ASP.NET, MVC       Comments Off on The MVC platform: interacting with the ActionMethodSelectorAttributes

In the one of the latest”s posts, we’ve seen how we can use the AcceptVerbsAttribute to limit the valid HTTP methods that can be used for requesting the execution of an action method. Today we’ll take a closer look at how these  items are used at runtime (ie, we’ll see how they are used internally by the platform). Lets start by looking at the ActionMethodSelectorAttribute class. In the  RC version, it’s really a simple abstract class with only one method:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public abstract class ActionMethodSelectorAttribute : Attribute {
   public abstract bool IsValidForRequest(
                                 ControllerContext controllerContext, MethodInfo methodInfo);
}

The idea is to insert a base class that you can extend so that you can interact with the runtime and check if some precondition is valid before executing an action method. Now, the real question is when will these classes be called and who is responsible for finding them and using them at runtime.

If you’ve been reading this series, you already know that I’ve written about the IActionInvoker and its default ControllerActionInvoker implementation. In the RC release, there have been some changes (don’t forget that I’ve written that post a long time ago). Internally, ControllerActionInvoker,InvokeAction will defer most of the work into two classes: ControllerDescriptor and ActionDescriptor (which is obtained from the ControllerDescriptor).

In fact,the main responsability of the ControllerDescriptor (by default,you’ll be using the type ReflectedControllerDescriptor) is getting an ActionDescriptor that “abstracts” the action that should be executed for the current request.

Internally, when the ReflectedControllerDescriptor tries to get an ActionDescriptor (btw, you’ll get a ReflectedActionDescriptor),  it ends up running the selection filters that have been applied to the current action method (if any, that is). And that’s how your custom ActionMethodSelectorAttributes end up running. There’s one interesting thing regarding the internal implementation of this feature: if any of the applied ActionMethodSelectorAttributes don’t return true when the IsValidForRequest method is executed, then the FindAction method of the ReflectedControllerDescriptor returns null as if the action you requested didn’t exist. This ends up the current request processing and returns 404 to the client.

The important thing to keep in mind is that if you apply a ActionMethodSelectorAttribute to a method, it will run before all the existing filters and if its IsValidForRequest method returns false, it will end up the processing of the request and none of your filters or action code will ever execute. Keep this in mind when you create your own ActionMethodSelectorAttribute derived classes.

And that’s it for today. Keep tuned for more on the MVC platform.

Feb 03

The MVC platform: more on dropdowns and listboxes

Posted in ASP.NET, MVC       Comments Off on The MVC platform: more on dropdowns and listboxes

A few days ago I’ve talked about how you could use the helpers to generate dropdowns and listboxes. As I’ve said, you need to build a collection of SelectListItems in order to build these controls. What I didnt’ mentioned at the time was that there is an easy way to convert a custom collection (ie, something which implements IEnumerable<T> interface) into a collection of SelectListItems. To do that, just instantiate the SelectList (or MultiSelectList, if you’re working with listboxes and want to select several values) class.

Here’s a quick example. Suppose you’ve got a class that looks like this:

public class Item    {
    public Int32 Id { get; set; }
    public String Description { get; set; }
}

And that you’ve also got a collection with several items:

var items = new[] {
      new Item {
                  Id = 1,
                  Description = "first"
          },
      new Item {
                  Id = 2,
                  Description = "second"
          },
      new Item {
                  Id = 3,
                  Description = "third"
          }
};

And that you want to fill a dropdown and select item 2. Here’s  how you can do that (I’m using a non-typed view here since I’m in a hurry :),,):

ViewData["optionsDrop"] = new SelectList( items, "Id", "Description", 2 );

As you can see, I’m passing the collection and saying that the Id property should be used for getting the value of the OPTION element and that the Description will return the text for that OPTION element. I’m also saying that element with value should be selected by default. Now, you only need to ensure that your dropdown is named optionsDrop and you’re ready to go:

<%= Html.DropDownList(  "optionsDrop", "Choose an option"   ) %>

And that’s it. More on the MVC platform on future posts.

Feb 03

The AcceptVerbsAttribute was introduced in a previous release of the framework and its main objective is to let restrict an action method to certain HTTP method(s) (PUT, POST, etc). So, lets reuse the default web site that is created from the ASP.NET MVC and change the About action method default so that it can only be used through a post request. To achieve this, you only need to add the AcceptVerbsAttribute to the method:

[AcceptVerbs("post")]
public ActionResult About() {
    return View();
}

And now if you try to execute this action from a request that isn’t made through a post you’ll get a 404 error. You’ll trigger this error if you try to execute this action through the About option you’ve got on the top menu.

When you use this class, you have two options:

  • you can specify the allowed verbs though the constructor that accepts a params arrays of strings;
  • You can use the overloaded constructor which receives a value from the HttpVerbs enumeration, which, as you might expect is a flags enumeration.

As a side note, take a look at the code and check the way the HttpVerbs enumeration is implemented…yep, they’re using the left shift operator in order to shift the existing bits in 1 n bits to the left. I find this interesting because most implementations of these enumerations will only use integers (calculated by multiplying the previous value by 2). Ok, back to business…

The AcceptVerbsAttribute expands the abstract ActionMethodSelectorAttribute class which ony has one method:

public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);

As you might expect,AcceptVerbsAttribute implements this method by recovering the HTTP method from the current request and by checking if  is is in the allowed list of verbs allowed by the current instance. And that’s it…there’s really nothing more to say about this class. You’re probably wondering on how this class is used by the runtime,but we’ll leave that for a future post. Keep tuned!

Feb 02

MVC platform: filling form’s fields from collection is broken for strongly typed views

Posted in ASP.NET, MVC       Comments Off on MVC platform: filling form’s fields from collection is broken for strongly typed views

Problems and workaround described here.

Feb 02

The MVC platform: more breaking changes in my posts

Posted in ASP.NET, MVC       Comments Off on The MVC platform: more breaking changes in my posts

A few days ago,  I’ve talked about the BindAtrtibute class and on how you needed to set the Prefix to an empty string so that it wouldn’t look for data prefixed by a specific name. Since most people ended up setting the prefix attribute, the team changed the default behaviour and now the binding uses the empty string prefix by default.

Feb 02

Yesterday I’ve presented the main properties and methods of the TagBuilder class. Today, we’re going to reuse those ideas and build an extension method that renders an image inside an anchor (unfortunately, the image helper methods are defined in the futures assembly and the current release of the anchors won’t let you pass HTML for its content). Before going on, I’d like to say two things:

  1. This isn’t going to be a complete example. What I mean by this is that I’m going to pick up a general form of helper and implement only that form (so, you won’t have all those overloads you generally end up having with the official methods);
  2. If I had to implement this scenario in the real world, I’d probably go with “straight HTML” and I’d use the Url helper methods for getting the correct urls.

Having said this, I still believe that building a simple example like this is good and might help you get a better grasp of the code used by the helpers. The idea is to have something like this:

<%=
   Html.ActionLinkWithImage(
           "~/Content/add.png", //relative image url
           "About", //controller action
           "Home", //controller
           null , //route values
           null, //link html attributes
           new { style = "border: none"} //image html attributes
           )
%>

As I said,I’m picking only one form (based on the anonymous object syntax) and I’m using it through out this example. You should be able to extend this sample with more overloads that give you more options and reduce the code you need to write if you’re note interested in setting all these parameters. Let’s see how easy it is to build this helper. Here’s the code:

public static class ImageWithAnchorHelper {
    public static string ActionLinkWithImage( this HtmlHelper htmlHelper,
                                     String relativeImageUrl,
                                     String actionName,
                                     String controllerName,
                                     Object routeValues,
                                     Object linkHtmlAttributes,
                                     Object imageHtmlAttributes )  {
        var url = GetUrlForLink( htmlHelper,
                                 actionName,
                                 controllerName,
                                 routeValues,
                                 null,
                                 null,
                                 null );

        var tagBuilder = BuildTagForLink(
                                    htmlHelper,
                                    GetImageHtml( htmlHelper, relativeImageUrl, imageHtmlAttributes ),
                                    linkHtmlAttributes, url );
        return tagBuilder.ToString( TagRenderMode.Normal );
    }
    private static TagBuilder BuildTagForLink( HtmlHelper htmlHelper,
                                               String imageHtml,
                                               Object linkHtmlAttributes,
                                               String url ) {
        var tagBuilder = new TagBuilder( "a" ) {
                                     InnerHtml = imageHtml
                         };
        tagBuilder.MergeAttributes( new RouteValueDictionary( linkHtmlAttributes ) );
        tagBuilder.MergeAttribute( "href", url );
        return tagBuilder;
    }

    private static String GetIma
geHtml( HtmlHelper helper,
                                        String relativeImageUrl,
                                        Object imageHtmlAttributes )  {
        var imageUrl = new UrlHelper( helper.ViewContext.RequestContext ).Content( relativeImageUrl );
        var imageTag = new TagBuilder( "img" );
        imageTag.MergeAttribute( "src", imageUrl, true );
        imageTag.MergeAttributes( new RouteValueDictionary( imageHtmlAttributes ), true );
        return imageTag.ToString( TagRenderMode.SelfClosing );
    }

    private static String GetUrlForLink( HtmlHelper html,
                                         String actionName,
                                         String controllerName,
                                         Object routeValues,
                                         String protocol,
                                         String hostName,
                                         String fragment ) {
        var urlHelper = new UrlHelper( html.ViewContext.RequestContext );
        var url = urlHelper.Action( actionName,
                                    controllerName,
                                    new RouteValueDictionary(routeValues),
                                    protocol,
                                    hostName );
        if( !String.IsNullOrEmpty( fragment ) ) {
            url += String.Concat (“#”, fragment);
        }
        return url;
    }
}

As you can see, the ActionLinkWithImage method extends the HtmlHelper class and is the only public entry point of these helpers (all the other methods are private). The method starts by getting the url for the current action. If you look at the code used by the helpers, you’ll see that they use the GenerateUrl method for getting the current url. Unfortunately, the method is internal and so we can’t use it without resorting to reflection. On the other hand, we can use the UrlHelper class and its Action method. Lets take a closer look at the GetUrlForLink method. As you can see, we start by instantiating a UrlHelper object:

  var url = urlHelper.Action( actionName,
                                    controllerName,
                                    new RouteValueDictionary(routeValues),
                                    protocol,
                                    hostName );

In this case, protocol and hostname are always null, but I’ve decided to leave the necessary code for making the adaptation of the GetUrlForLink easy for future helpers. That’s why I’ve also made the method receive a fragment, even though the main helper doesn’t accept it (as an exercise, you can always add more overloads which use those parameters: the private methods support them so it’s only necessary to add more overloads of the ActionLinkWithImage that receives them). A fragment is always in the form of http://…..#fragment. That’s why you’ve got that String.Concat there for joining an eventual fragment with the current url:

if( !String.IsNullOrEmpty( fragment ) ) {
            url += String.Concat (“#”, fragment);
}

And that’s it for the GetUrlForLink method. Getting the HTML for the inner image is also easy, as you can see by looking at the GetImageHtml method. We start by creating an UrlHelper object for getting the  correct url for the image. The main difference (when compared with the previous snippet) is that, in this case, we’re passing a relative url and so we’re using the Content method:

var imageUrl = new UrlHelper( helper.ViewContext.RequestContext ).Content( relativeImageUrl );

The “hard work” of getting the HTML is done by the TagBuilder class. Notice that I’m simply using the MergeAttribute and MergeAttributes method in order to set the attributes applied to the final IMG tag. The HTML is obtained by calling an overload of the ToString method and passing a value from the TagRenderMode enumeration to generate an image on the form <img … />:

var imageTag = new TagBuilder( "img" );
imageTag.MergeAttribute( "src", imageUrl, true );
imageTag.MergeAttributes( new RouteValueDictionary( imageHtmlAttributes ), true );
return imageTag.ToString( TagRenderMode.SelfCl
osing );

After having the inner HTML and the correct link url, we delegate the remaining work to the BuildTagForLink method:

private static TagBuilder BuildTagForLink( HtmlHelper htmlHelper,
                                               String imageHtml,
                                               Object linkHtmlAttributes,
                                               String url ) {
        var tagBuilder = new TagBuilder( "a" ) {
                                     InnerHtml = imageHtml
                         };
        tagBuilder.MergeAttributes( new RouteValueDictionary( linkHtmlAttributes ) );
        tagBuilder.MergeAttribute( "href", url );
        return tagBuilder;
}

As you can see, most of the work is done (once  again) by the TagBuilder class. Since we’re passing HTML for the link’s content, we just pass that value to the InnerHtml property without encoding it (as happens with the current Link extension methods). And that’s all that is needed for having a helper that generates HTML. As I’ve said, this is only demo code. In a real work extension method you’re expected to provide more overloads and perform more validations. I’ll leave those modifications for those that intend to make this a “real world” extension method helper.

Keep tuned for more on the ASP.NET MVC.

Feb 01

The MVC platform: the TagBuilder class

Posted in ASP.NET, MVC       Comments Off on The MVC platform: the TagBuilder class

In the last posts we’ve seen that the platform introduces several helpers for generating the HTML for the controls you want to put in a page. Today we’re going to look at the class that is responsible for outputting that HTML and that is used internally by all those helpers: the TagBuilder class.

The only public constructor of the TagBuilder class receives the name of the HTML tag you want to generate. Besides that, you can also set its inner HTML (by using the InnerHtml property) or the text the control should render (by using the SetInnerText method). Another of the properties exposed by the class is the IdAttributeDotReplacement property. This property is used for indicating the character that should be used when rendering the client ID for composite names. For instance, the TextBox helper method can be used like this:

<%= Html.TextBox(“User.Name”) %>

In the old days, you’d get User.Name as the id of HTML INPUT that is generated by that line. Unfortunately, that didn’t work very well when you’re using JQuery. That’s why this property was added in this release. Btw, you should know that the current release uses the ‘_’ char as the separator. If you need to change that char to something else, then you should set the Html.IdAttributeDotReplacement property. BY doing this, you’ll end up setting the IdAttributeDotReplacement property on the TagBuilder instance that is used to generate the HTML.

Besides the text/inner HTML and the separator used in “complex names”, there are also other methods which you can use. For instance, you can add an existing css class by calling the AddCssClass method. You can also merge attributes by calling the MergeAttribute method. This method will let you override or append a specific value to an attribute that is going to be rendered on the HTML that is generated by this class. There really isn’t much to say about this class. The important thing to keep in mind is that you should use it when you’re building your own HTML helpers.

And that’s all for today. More about the MVC on the next posts.

Jan 31

The MVC platform: generating textareas

Posted in ASP.NET, MVC       Comments Off on The MVC platform: generating textareas

This is going to be the last post on the Html extension methods and we’re going to end with TEXTAREAS. If you’ve been following these posts, then you know what to expect: several overloads of a method which let you define the attributes you’d generally set up on a TEXTAREA control.

The simplest of the overloads of the TextArea method will let you define the name of the generated control:

<%= Html.TextArea( "name" ) %>

By default, you’ll end up with a 20 columns x 2 rows HTML TEXTAREA. If that doesn’t work for you, you can always use the overload which sets those values:

public static string TextArea(this HtmlHelper htmlHelper,
                                                 string name,
                                                 string value,
                                                 int rows,
                                                 int columns,

                                                 object htmlAttributes)

You’ll also be happy to know that all the previous “tricks” work with these helpers too. So, if you’ve got an entry on the ViewData dictionary with the same name as the one  you pass to the name parameter of the methods, then the generated TEXTAREA will automatically render that value as its content.

You can also use validators with these helpers (if you want to know more about validation, please check this post). As you’d expect,you also have an overload which lets you specify the HTML attributes you which to render.

And that’s it. As you can see,the helpers to cut off the work need for generating HTML from the server side and do have similar APIs. So, if you know how to use one, you really know how to use the others. Keep tuned for more MVC stuff!

Jan 31

,,The MVC platform: more form extension methods

Posted in ASP.NET, MVC       Comments Off on ,,The MVC platform: more form extension methods

I’ve already talked about several method extensions helpers for injecting forms in a page. However, the latest release has introduce a couple more methods for doing that and I’ve thought I’d write a quick post on those new methods.

Basically, you’ll have several overloads named BeginRouteForm which let you set the form’s action method from a specific route. As you’d expect, you use it the same way you use the “Old” BeginForm method (check this post to get more info on what I mean). Here’s a quick example of what I mean:

<% using( var frm = Html.BeginRouteForm("DefaultRoute")) {%>
…//control definition
<%}%>

In the previous example, I’m using the simplest of the overloads: it only takes the name of the route that you want to use to build the form’s action url. As I’ve said, there are others (too much to put here so I’ll just redirect you to the FormExtension.cs file.

Jan 30

Today we’ll keep looking at the helpers and see how we can add dropdowns and listboxes to our views. As you might expect, there are some helper methods that render the corresponding SELECT HTML element. They’re adequately named DropDownList and ListBox and,as you might expect, you’ll find several overloads of each. The main difference between then is that with the ListBox you’ll be able to select several items simultaneously. Here’s some demo code that shows how to create and fill the lists which will be shown on the page:

<%= Html.DropDownList(
                    "optionsDrop",
                     new []
                         {
                                 new SelectListItem
                                     {
                                             Text = "Option 1",
                                             Value = "opt1"
                                     },
                                  new SelectListItem
                                     {
                                             Text = "Option 2",
                                             Value = "opt2"
                                     },
                                  new SelectListItem
                                     {
                                             Text = "Option 3",
                                             Value = "opt3"
                                     }
                },
               "Choose an option"  
             ) %>
<br />
<%= Html.ListBox(
                    "optionsList",
                     new []
                         {
                                 new SelectListItem
                                     {
                                             Text = "Option 1",
                                             Value = "opt1"
                                     },
                                  new SelectListItem
                                     {
                                             Text = "Option 2",
                                             Value = "opt2"
                      &#16
0;              },
                                  new SelectListItem
                                     {
                                             Text = "Option 3",
                                             Value = "opt3"
                                     }
                },
               "Choose an option"  
             ) %>

Since this is demo code and my main objective is to show you how you can render a dropdown, I’ve just created some dumb SelectListItems to fill the list of items displayed by the HTML SELECT element generated by the helpers. In the “real world” you’d probably have a collection of items that you’d want to show in a dropdow or in a listbox. In those cases, you’d be encouraged to perform the transformation from the custom items in that collection into the SelectListItems in the  controller.

Going back to the example, I’d like to mention that the SelectListItem class is a simple class which exposed three properties:

  • Text: used for setting the text of the OPTION element contained in the dropdown or listbox;
  • Value: used for  defining the value of the OPTION element used for representing a rendered entry;
  • Selected: boolean property that indicates if an item is selected.

Btw, in the previous snippet, we’re using one of the overloads which receives an optional string label. This label is added to the items on the list without a specified value (ie, the string you passed for the label parameter is converted into a SelectListItem with an empty string Value and with the Selected property set to false – oh, and yes, with its Text property set to the text you’ve passed through the label parameter). As you’ve seen in some of the previous posts, you also have overloads that let you specify the html attributes you want to set up on the generated HTML element.

More interestingly, you can make the dropdown or listbox render automatically the items passed from the controller through the ViewData property (which is really what you want when you have a custom collection which the controller converts into SelectListItems as I’ve suggested above). You have 2 options:

  • if you use the dictionary approach without a “strongly typed” view, you’ll need to have an entry on the ViewData dictionary with the same name as the one that is passed to the name parameter of the DropDownList or ListBox  methods you’re calling;
  • if you’re using a “strongly typed” view, then you need to guarantee that the object that is passed to the view has one property with the same name as the name you’ve passed to the DropDownList (or ListBox) method you’re invoking.

So, if you’re using approach 1, you need to have something like this in your action method:

ViewData["optionsDrop"] = new[] {
                new SelectListItem
                    {
                            Text = "Option 1",
                            Value = "opt1"
                    },
                new SelectListItem
                    {
                            Text = "Option 2",
                            Value = "opt2"
                    },
                new SelectListItem
                    {
                            Text = "Option 3",
                            Value = "opt3"
                    }
        };
//the code is similar for the ListBox method

Notice that I’m passing the same name as the one that is passed to the DropDownList/ListBox method in the previous example! In scenario 2, you’d start by having a class. Here’s the quickest one I could build:

public class Dto    {
      public IEnumerable<SelectListItem> optionsDrop {
          get {
              return new[] {
                                                new SelectListItem
          
                                          {
                                                            Text = "Option 1",
                                                            Value = "opt1"
                                                    },
                                                new SelectListItem
                                                    {
                                                            Text = "Option 2",
                                                            Value = "opt2"
                                                    },
                                                new SelectListItem
                                                    {
                                                            Text = "Option 3",
                                                            Value = "opt3"
                                                    }
                                        };
          }
      }

      public IEnumerable<SelectListItem> optionsList {
          get {
             //similar to the other property…
          }
      }
}

And then you could reduce the method call in your pages to this:

<%= Html.DropDownList(
                    "optionsDrop",
                     "Choose an option"  
             ) %>
<br />
<%= Html.ListBox(
                    "optionsList" 
             ) %>

And that’s it! The dropdown and listbox controls will automatically get the correct SelectListItem from the ViewState initialized by the controller. Interestingly, there’s not an overload for the ListBox method that lets you pass a name and a value for the label (I don’t know what’s the rationale behind that decision, but if you need that additional entry and you want to pass the SelectListItems from your controller, then you’ll need to add that default entry to the list that is passed from the controller). Do keep in mind that you’ll only get this automatic hookup if you don’t pass a valid collection of SelectListItem elements to the helper methods!

If you’re curious, then you’d probably like to know that the assembly of the HTML returned by each of the methods is done by a private method called SelectInternal. There’s also another important helper called GetSelectData which is called when you don’t pass a collection of SelectListItems explicitly to these methods (ie, this method tries to get the SelectListItem collection from the ViewState passed from the controller). The code for these private methods is really simple, so I’ll leave it to you to explore it.

And that’s all for today. Keep tuned because there’s more to come about MVC.

Jan 29

Today we’ll keep talking about the MVC framework and we’ll see how easy it is to add anchors to our apps. In the past, we’ve already seen that the framework introduces a class called UrlHelper that you can use in order to get the correct url for a specific action. So, adding an anchor to a view could be done through code like this:

<a href="<%= this.Url.RouteUrl( "Default", new { action = "About" } ) %>" title="Navigate to about page">
        Go to About
</a>

(btw, I’m assuming that you’ve created a new default project and the previous code is reusing the routes introduced by that template).

As you can see, we’re writing the complete html for the anchor and using the helper in order to get the correct url for the href attribute. You can achieve the same result by using the ActionLink or RouteLink extension methods “added” to the HtmlHelper class. Here’s a snippet with both of them in action:

<%= Html.ActionLink( "Go to About", "About" ) %>

<%= Html.RouteLink( "Got  to About", new { action = "About"} ) %>

As you can see, in this case the syntax for RouteLink is not as direct as the one you’ll get with ActionLink. And there’s a reason for that. Generally, you’ll use the ActionLink method when you want to specify an action and controller. On the other hand, if you also want to set the name of the route, then you can use the RouteLink method.

Both methods have several overloads which let you specify:

  • the name of the controller;
  • the name of the desired action;
  • the dictionary with values that should be passed to the route parameters (ie,an element of type RouteValueDictionary with values that are passed to the existing route parameters);
  • the HTML attributes that should be applied to the generated anchor;
  • the HTML protocol you want to use;
  • the hostname (if you want to set it explicitly);
  • the fragment used to identify a named anchor (so that you can specify urls a la http://…something#name).

Additionally,the RouteLink method will also let you pass the name of the route (as we’ve seen above). Internally, both methods end up calling the more general GenerateLink method (which is public and static and defined by the HtmlHelper class).

One more note before ending: the more astute readers have already spotted that the 1st example (where we specified the URL through the UrlHelper class) generates slightly different HTML. The difference lays on the HTML title attribute, which isn’t generated when we used the HtmlHelper extension methods. If you need to set that attribute, you’ll have to use one of the overloads that receives the HTML attributes that should be rendered (don’t forget that at least one of the overloads receives an Object parameter, which means that you can use anonymous objects for setting the attributes you need).

And that’s all for today. More about the MVC framework on the next posts.

Jan 28

ASP.NET RC released

Posted in ASP.NET, MVC       Comments Off on ASP.NET RC released

Get all the details from Scott Gu.

Jan 26

The MVC platform: wrapping up the textbox helper

Posted in ASP.NET, MVC       Comments Off on The MVC platform: wrapping up the textbox helper

After a long pause, it’s time to go back to the MVC series. Today I’ll wrap up with a last post which mentions a scenario I’ve missed when I talked about the automatic hooking of properties to form fields. In a previous post, we’ve seen how easy it is to associate fields to simple properties of an object. Today, we’re going to see how easy it is to bind complex properties (ie, properties which are classes themselves). We’ll reuse the class presented in one of the previous posts and we’ll change it so that it has a complex property:

public class UserInfo {
    public String Name { get; set; }
    public String Password { get; set; }
    public String Sex { get; set; }
    public AuxiliaryInformation AuxiliaryInformation{ get; set; }
}
public class AuxiliaryInformation {
   public String MoreInfo { get; set; }
}

As you can see, this is really a contrived example, but it will do for now since my only objective is to show you how to hook up the complex property to the control. So, the big question is what must you do so that the MoreInfo subproperty is automatically filled with the control’s value? Easy: just set the name parameter of the helper to the “complete” name of the property. Here’s the code I’ve added to the existing HTML code presented in an earlier example:

<label for="AuxiliaryInformation.MoreInfo">Auxiliary info:</label>
<%=Html.TextBox("AuxiliaryInformation.MoreInfo")%>

And that’s it. If you have a method similar to the one presented in this post, you’ll notice that the AuxiliaryInformation property is correctly filled with the value passed from the HTML input you’ve added to the page. I’ve run some tests and you’ll be happy to know that the property is correctly filled even when you have readonly complex properties (that is, even if AuxiliaryInformation is read-only, you’ll be able to pass a value to the  MoreInfo “sub-property”).

Do notice that you need to pass the same value to the for attribute of the HTML label so that it is associated with the generated textbox. And that it’s it for this post. Keep tuned!

Dec 26

In the lasts posts, we’ve started looking at some of the HtmlHelper extension methods that you can use to render controls on your forms (we’ve looked at several methods you can use to render HTML INPUT controls). Today we’re going to keep looking  at the extenders, but we’ll concentrate on how to generate forms on your views.

The FormExtensions.cs file contains several extension methods that you can use to create forms. You’ll find several overloads of the BeginForm and EndForm methods. The BeginForm method lets you set up the attributes you’d normally apply to an HTML form (ie, action and method). There are overloads of this method that will let you fill those attributes automatically or you can use any of the overloads that lets you specify the value of each of those attributes. As you might expect, some of the overloads let you pass the name of the controller/action for specifying the action (ie, the url from where your form will post its data).

The BeginForm methods render the <form> begin tag into the response stream and returns an instance of type MvcForm. This simple class implements the IDisposable method. Its Dispose method implementation is responsible for closing the end form tag. So, you could generate a form by writing something like this (I’ll be rewriting the form I’ve presented in one of my previous examples):

<% using( var frm = Html.BeginForm("HandleFormData", "Home")) {%>
<label for="name">Name:</label><%=Html.TextBox("name")%>
  <%=Html.ValidationMessage("name", "*")%>
  <br />
  <label for="Password">Password:</label><%=Html.Password("Password")%>
  <%=Html.ValidationMessage("name", "*")%>
  <br />
  <label for="male">Male:</label>
  <%=Html.RadioButton("sex", "male", new {id = "male"})%>
  <label for="female">Female:</label>
  <%=Html.RadioButton("sex","female",new {id = "female"})%>
  <input type="submit" id="myBt" value="Try to submit" /> <br />
  <%=Html.ValidationSummary()%>
<%}%>

If you don’t really enjoy the using syntax, then you can use the BeginForm/EndForm pair:

<%Html.BeginForm("HandleFormData", "Home"); %>
     <label for="name">Name:</label><%=Html.TextBox("name")%>
      <%=Html.ValidationMessage("name", "*")%>
      <br />
      <label for="Password">Password:</label><%=Html.Password("Password")%>
      <%=Html.ValidationMessage("name", "*")%>
      <br />
      <label for="male">Male:</label>
      <%=Html.RadioButton("sex", "male", new {id = "male"})%>
      <label for="female">Female:</label>
      <%=Html.RadioButton("sex", "female", new {id = "female"})%>
      <input type="submit" id="myBt" value="Try to submit" /> <br />
      <%=Html.ValidationSummary()%>
<%Html.EndForm();%>

Notice that since the BeginForm doesn’t return a string, you must not use the Response.Write “shortcut” (ie, <%= %>) and you must end up the statement with a ;. So, now you’ve got at least three ways of generating a form:

  • you can use the classic approach, where you write the HTML directly (as we’ve seen in the oldest examples);
  • you can use the disposable syntax (based on the using helper);
  • you can use the BeginForm/EndForm pair of methods.

Any of these options works well, so choose the one you prefer (in most of the examples I’ve built, I did use the first approach, where I explicitly write the FORM tag). On the next post, we’ll keep up looking at the HtmlHelper extension methods. Keep tuned!

Dec 24

New features in ASP.NET 3.5

Posted in ASP.NET       Comments Off on New features in ASP.NET 3.5

I’ve just noticed that there’s a Wrox Blox by Wally which presents the new ASP.NET features introduced by .NET 3.5 Service Pack 1. If you want to know more about these features, then go ahead and read the blox.

Dec 19

MVC Design Gallery announced

Posted in ASP.NET, MVC       Comments Off on MVC Design Gallery announced

Scott Gu announced the new MVC Design Gallery today. He also talked about several changes that will be presented on the RC version of ASP.NET MVC.

Dec 18

The MVC framework – refactoring the previous example

Posted in ASP.NET, MVC       Comments Off on The MVC framework – refactoring the previous example

In the last post we’ve seen a really simple example of how to use the existing HtmlHelper methods for building a simple form. We’ve also seen how to validate those results and how to pass them for further processing. to achieve that, we used all “low-level” methods provided by the framework (ie, we’ve resorted to using the Request.Form collection to get all the submitted values from the form).

At the time, I said that there was an easier way to do the same with less code. In this post I’ll show you how! We’ll start by creating a new class for keeping the info introduced by the user. I’m calling it UserInfo:

public class UserInfo    {
        public String Name { get; set; }
        public String Password { get; set; }
        public String Sex { get; set; }
}

Now, the idea is to use the binding helpers to get an instance of type UserInfo automatically from the data that is submitted by the form which should be passed to our action method. Here’s the code for the HandleFormData:

public ActionResult HandleFormData([Bind(Prefix = "")]UserInfo user) {
   if (user == null ||
        String.IsNullOrEmpty(user.Name) ||
         user.Name.Length < 4) {
                ViewData.ModelState["name"].Errors.Add(
                      "name must have more than 4 chars");
                return View("Index");
    }
    return View("UntypedUserInfo",user);
}

If you compare this code with the previous example, you’ll notice that we’ve improved its readability while simultaneously reducing the number of lines of code. Lets take a deeper look at what’s going on here:

  • We’ve changed the HandleFormData method so that it receives an instance of UserInfo. The idea is to delegate the creation and initialization of that instance to the framework;
  • The BindAttribute instructs the framework to create and set the values of user from the values submitted by the form. The user of Prefix is necessary in this case. Without it, and by default, the framework would search for fields named user.name, user.sex, etc. (the  name user. comes from the name of the parameter). Another thing to keep in mind is that the framework will use the DefaultModelBinder class for initializing the class. I’ve already written about the binding model in the past, so now might be a good time to review that info. btw,Scott Gu has also a good post on how to use this feature.
  • Instead of using an untyped view,we’re now using type view so that we have compilation verification and intellisense when filling the info on our view. That’s why we’re forwarding the UserInfo to the View call.

I’m not sure on what you think about this, but I do like the end result. Yes, during the first time you might think that there’s simply too much magic going on here, but after understanding the basics and understanding what’s going on, it’s undeniable that we do really get better results (cleaner code which is really more expressive, right?).

We still need to change the view. The first thing to do is to change its codebehind file:

public partial class UntypedUserInfo: ViewPage<Data> {
}

And now, we can simply change the code on the aspx file to this:

<asp:Content ID="Content1"
         ContentPlaceHolderID="MainContent" runat="server">
         name: <%= Html.Encode( ViewData.Model.Name ) %><br />
         password: <%= Html.Encode(ViewData.Model.Password)%><br />
         sex: <%= Html.Encode(ViewData.Model.Sex)%><br />
</asp:Content>

Ok, to me this looks much  better. What do you think?

We’ll keep going on the next posts. Stay tunned!

Dec 18

The MVC platform – the HtmlHelper class (part III)

Posted in ASP.NET, MVC       Comments Off on The MVC platform – the HtmlHelper class (part III)

After the slight detour for introducing validation support, it’s time to go back to the helpers which you can use for generating HTML controls from your views. I think that the second post on the HtmlHelper class should have been more than enough for understanding how things work, so in this post I’ll just jump into a description of the remaining methods exposed by the InputExtensions static class.

Besides the TextBox method (which, as we’ve seen, is  used for generating simple textboxes), you’ll also find:

  • CheckBox: used fore generating checkboxes (ie, HTML elements similar to <input type=”checkbox”>);
  • Hidden: used for inserting hidden textboxes (ie, HTML INPUT elements with the type set to hidden);
  • Password: ok, you’ve guessed it! It’s used for generating input fields that will be used for entering passwords (ie, this method inserts <input type=”password”> elements on the page);
  • RadioButton: used for inserting radio buttons elements on the page (ie, this method inserts <input type=”radio”> on the page).

Lets build a form that shows how to use some of these methods. To do that, I’ll just change the code that exists in the Index view you get whenever you create a new MVC project form the VS template. Here’s what I’ve added:

<form method="post" action="<%= Url.Action("HandleFormData","Home") %>">
      <label for="name">Name:</label><%= Html.TextBox( "name" ) %>
      <%= Html.ValidationMessage("name","*")%>
      <br />
      <label for="password">Password:</label><%= Html.Password( "password" ) %>
      <%= Html.ValidationMessage("name","*")%>
      <br />
      <label for="male">Male:</label>
      <%= Html.RadioButton("sex", "male",  new {id = "male"}) %>
      <label for="female">Female:</label>
      <%= Html.RadioButton("sex", "female",  new { id = "female" })%>
      <input type="submit" id="myBt" value="Try to submit" /> <br />
      <%= Html.ValidationSummary() %>
</form>

So, what do we have here:

  • we’re using labels that are associated to each of the controls;
  • we’re setting the ID of each radio button explicitly so that we can associate a label to each option. Btw, and since we’re talking about radio buttons, notice that the previous snippet won’t select any option by default. If you need that you can use one of the overloads that sets the checked property of the control or, way better, add code that sets the ViewData dictionary of the control to the value you want (for instance, lets say you want to select male by default. Then you’d add this to the method that renders the initial form: ViewData["sex"] = "male";). Notice that the second option is better because it will let you maintain the value introduced by the user if there’s an error on the form (the first will always set the option to the predefined value and the value selected by the user will be lost). More about this on the next paragraphs;
  • we’re using yesterday’s ideas and we’re reusing the logic for validation;
  • the form ends up calling the HandleFormData action method on the Home controller.

The HandleFormData action method is responsible for performing validation on the incoming data. If everything is OK, it will simply redirect that info to another view which, in this case, will only display that info on a aspx page. Here’s the code for HandleFormData:

public ActionResult HandleFormData() {
    var name = Request.Form["name"];
    ViewData["name"] = name;
    ViewData["password"] = Request.Form["password"];
    ViewData["sex"] = Request.Form["sex"]; 

    if (String.IsNullOrEmpty(name) || name.Length < 4) {
        var state = new ModelState()
                        {
                            AttemptedValue = name
                        };
        state.Errors.Add("name must have more than 4 chars.");
        ViewData.ModelState.Add("name", state);
        return View("Index");
    } 
       return View("UntypedUserInfo");
}

Ok, not really the best code in the world, but it will do for this short demo. As you can see, I start by filling the view data dictionary so that the controls on the form will have the values entered by the user if there’s an error.The same view data will also be used by the UntypeduserInfo view which is only responsible for showing the info introduced by the user. here’s the code on that page:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="UntypedUserInfo.aspx.cs" Inherits="MvcDemo.Views.Home.UntypedUserInfo" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    name: <%= Html.Encode( ViewData["Name"] ) %><br />
    password: <%= Html.Encode( ViewData["Password"] ) %><br />
    sex: <%= Html.Encode( ViewData["Sex"] ) %><br />
</asp:Content>

If you’re an “experienced” ASP.NET MVC developer, you’ll be thinking that there must be a better way of doing this (and yes, I believe there is and we’ll show it in a future post), but this small sample should be more than enough to give you an idea of what you can do with the helpers.

And I believe that’s all for today. We’ll keep looking at the MVC framework on the next posts. Keep tuned!

Dec 17

Today we’re going to look at the validation support introduced by the framework. Do keep in mind that we’re not talking about using validators like the one you have in the ASP.NET web forms world. Nop! here validators are only responsible for showing an error message to the user. In practice, this means that you have to signal that a control has an incorrect value and the MVC framework will pick that info and show the appropriate error message where you’ve  dropped the “validator”.

The best way to understand this is to give a simple example. Let’s reuse yesterday’s form:

<form method="post" action="">
  <%= Html.TextBox( "name”) %>
  <input type="submit" id="myBt" value="Try to submit" />
</form>

We’ll also assume that we can only accept non-empty names with more than 4 characters on the name textbox. When that doesn’t happen, we will want to add a message saying that. In order to show a message next to the control, we can simply call the ValidationMessage method where we’d like to show the error message:

<form method="post" action="">
  <%= Html.TextBox( "name", "hallo", new { @class = "myInput"} ) %>
  <%= Html.ValidationMessage("name")%>
  <input type="submit" id="myBt" value="Try to submit" />
</form>

Notice that the ValidationMessage extension method will only be responsible for showing a specific error message. We still need to define that message and signal when there’s an error with the value passed to the control. As I’ve said, we’re only accepting non-null names with more than 4 characters. To signal that there’s something wrong with the value of a control we will need to add an error message to the  ModelState instance associated with that control. The simplest way to do this is to write the following code on the controller’s method that is responsible for handling the request:

var name = Request.Form["name"];
if( String.IsNullOrEmpty(name) || name.Length < 4 ) {
   ViewData.ModelState.AddModelError("name", 
                                                 "name must have more than 4 chars.");
}

If we run the page and write “la”, then this is what we’ll see:

validation1

The AddModelError method will end up creating a ModelState instance and it will associate it to an existing control named “name” (that is, if there isn’t any associated with the control identified by the first parameter) . Note that there’s also an overloaded version of this method which receives an exception.

There’s an interesting gotcha here which I must mention. The ViewDataDictionary.ModelState property presented in the previous snippet isn’t really of type ModelState. The fact is that it’s a property of type ModelStateDictionary which  is a dictionary of pairs string/ModelState (where the string identifies the control’s name on the page).

Now is probably a good time to look at the ModelState class. It’s really a simple class with only two properties: Attempted Value and Errors (i’m only showing its public API).

public class ModelState {
    public string AttemptedValue {
        get;
        set;
    }
    public ModelErrorCollection Errors {
        get {
            return _errors;
        }
    }
}

As you have probably guessed by now, calling the AddModelError method results in the instantiation of a new ModelError object which is added the to ModelState instance. The ModelError class is really simple and it has only two properties: Exception and ErrorMessage. One thing I didn’t mention is that you can add several error messages by calling AddModelError several times.

The AttemptedValue property of the ModelState class isn’t set up when you call the AddModelError method. This property is important and you can use it to pass a value that will be shown by the control. For instance, when you look at the previous figure,you’ll notice that the textbox is empty when there’s an error with the input. A better option would be to show the wrong value entered by the user. Here’s how you could do that:

var name = Request.Form["name"];
if( String.IsNullOrEmpty(name) || name.Length < 4 ) {
   var state = new ModelState() {
                    AttemptedValue = name
   };
   state.Errors.Add("name must have more than 4 chars.");
   ViewData.ModelState.Add("name",state);
}

If you load the page and pass it an incorrect value, you’ll notice that you’ll get the error message and that the textbox won’t loose the last introduced value.

Even though you can pass several error messages to a control, the truth is that with the current API, you’ll only see one error per validator associated to a specific control. You can easily change this behaviour (I’ll probably show an easy way in the next post) if you require.

Before ending this post, there’s still time to present the ValidationSummary method extension. As you’ve probably guessed, this method will show you all the error messages associated with the controls shown by the current view. It will generate an unordered list with all the errors maintained by all the ModelState instances that have been registered with the ViewDataDictionary instance.

When you use a summary, you probably will not want to repeat the error message in front  of the control. In those cases, you could probably identify the control that has an error with a special symbol (ex.: *) and just put the error message on the summary. To achieve this, you’ll need to specify the error message presented by the validator by calling one of the overloads of the ValidationMessage method that receives a validation message. Changing the view so that it looks like the following snippet is all that it takes to get this behaviour:

<form method="post" action="">
     <%= Html.TextBox( "name" ) %>
     <%= Html.ValidationMessage("name","*")%>
     <input type="submit" id="myBt" value="Try to submit" /> <br />
     <%= Html.ValidationSummary() %>
</form>

Finally, there’s still time to talk about the options you have to customize the style of the errors presente
d by the “validator” and the validation summary. The easiest way to customize them is to use the overloads that receive the attributes rendered by the control. Both methods have two overloads that will let you specify the values of the attributes: one uses the anonymous object approach; the other ends up using a dictionary. By default, the framework ends up using some predefined css style classes. You can always create your own too and then pass that info through one of the overload methods. Here’s a quick example:

<%= Html.ValidationMessage("name","*", new { @class="test"})%>

In this case, the predefined css class will be applied as an alternative css class, which means that the “test” css class will be applied to the span that holds the validation message. Notice that the textbox will still have a red border and in the current release I’m not sure that you’ll be able to change the applied css easily (I think there’s a bug on the code, but I’ll confirm it before talking about it).

And that’s all for today. Keep tuned!

Dec 16

The MVC platform – the HtmlHelper class (part II)

Posted in ASP.NET, MVC       Comments Off on The MVC platform – the HtmlHelper class (part II)

Today we’re going to keep talking about the methods associated with the HtmlHelper classes. In this post, we’ll concentrate on the extension methods defined on the InputExtensions.cs file that allow us to introduce several textboxes on a page (ie, HTML Input elements if you really want to  be picky). We’ll end up analyzing the three overloads of the TextBox method:

public string TextBox(string name)
public string TextBox(string name, object value)
public string TextBox(this string name, object value, object htmlAttributes)
public string TextBox(string name, object value, IDictionary<string, object> htmlAttributes)

The first overload lets you specify the name/id of the control. You can use that overload when you don’t want to explicitly specify the value of the textbox. The remaining overloads will let you set the value and attribute pairs you can define on the INPUT control (do notice that you can use the anonymous method approach or the dictionary approach).

The easiest way to use these helpers is illustrated on the next snippet (dropped on the aspx page):

<%= Html.TextBox( "name" ) %>

The previous line is responsible for injecting the following HTML on the page shown on the browser:

<input  id="name" name="name" type="text"  />

Lets suppose that you want to set the class to a predefined CSS style called myInput. Here’s one way of doing that:

<%=
          Html.TextBox( "name", //name/id of the textbo
                              null, //value shown
                              new { @class = "myInput"} ) //other attributes

%>

with the corresponding HTML:

<input class="myInput" id="name" name="name" type="text"  />

If you wanted, you could also use the overload which receives a dictionary (for this short illustration,using the anonymous object was more than enough,right?). As you can see, we didn’t pass anything to the value attribute. Nothing prevented us from passing a value to it, but it’s important to keep in mind that if you do that, you’ll loose the “automatic filling behavior”. “Auto what?” you’re asking? well, never mind the name. It’s just something I invented to explain what happens when you have an element whose key is the same as the id of a textbox and that doesn’t have an explicit value set.

To illustrate this approach, lets suppose that we have a simple form:

<form method="post" action="">
  <%= Html.TextBox( "name”) %>
  <input type="submit" id="myBt" value="Try to submit" />
</form>

It’s just a simple textbox and a submit button which will only refresh the current form  (ie, it will start a new request to the current url which will then instantiate the controller and will call the right method to handle the request and return a response back to the client). Yes,there are some helpers for generating forms too but we’ll leave that for future posts…

Now, if you have something like this in your controller’s method that handles the request and “calls” the view that had the previous snippet:

ViewData["name"] = Request.Form["name"];

You’ll always end up initializing the control with the last value that the user entered before submitting the form. Yes, you don’t need to do anything else (besides calling the TextBox method from the aspx page and passing it the same id as the key of the item that was passed into the view data dictionary). Interestingly, this behaviour will also work when you have strongly typed view. For instance, if you had a class that looked like this:

public class Data    {
        public String name { get; set; }
}

and the previous TextBox method call (<%= Html.TextBox( "name”) %>) then you could expect the textbox to have the value of the name property of that class with the following code:

return View( new Data{name = "Hooo"});

In other words, the value of the input HTML control will always be set to Hooo.

Do notice that this behaviour is slightly modified when you use validation. If you add a “model state” to your form and associate it with a control, then that value will always “overwrite” the other values you try to pass to the control. We’ll talk about simple validation on the next post (ie, we’ll interrupt the HtmlHelper analysis for introducing the validation classes introduced by ASP.NET MVC).

And that’s all for today. Keep tuned!

Dec 15

The MVC platform – the HtmlHelper class (part I)

Posted in ASP.NET, MVC       Comments Off on The MVC platform – the HtmlHelper class (part I)

After a long break, it’s time to go back to the MVC framework study. And today I’ll start from where I’ve stopped last time: the helpers. Today, I’m going to start talking about the HtmlHelper class which has lots of methods that you can use on your views for generating HTML. If you’ve downloaded the source code and then look at the HtmlHelper.cs file, you’ll be able to see that most of the methods you’ll discover through intellisense are defined by extension methods. Today I won’t talk about these methods. Instead, I’m going to concentrate on the methods defined directly on the class (ie, on the methods that are defined on the body of the class).

By default, the HtmlHelper exposes only a handful of properties for giving you access to:

  • the data dictionary that is passed to the view (ViewData property);
  • to the current route collection (RouteCollection property);
  • to the current context (ViewContext property);
  • to the current IViewDataContainer element (see more about this  interface in this post).~

Besides these properties, the class exposes several utility methods. Many of these could be exposed as static methods but the team decided to expose them as instance methods in order to maintain consistency across the API. Here’s a summary of the instance methods you’ll find  in the class:

  • AttributeEncode: used for encoding the values that you intend to pass to an attribute. There are two overloads of this method (the one that receives an Object will call the Convert.ToString method before  passing the value to the  HttpUtility.HtmlAttributeEncode method);
  • Encode: similar to the previous method, but in this case you’ll end up using the HttpUtility.Encode method (remember that the  HttpUtility.HttpAttributeEncode should only be used for double quoted attribute values);
  • EvalString/EvalBoolean: as you can see from their names, these methods are responsible for receiving a string that identifies an item on the ViewDataDictionary and for returning it to you (already casted to string or boolean).

Besides these instance methods, you’ll also find several static methods. For instance, there’s a GetFormMethodString which transforms a value from the FormMethod enumerations into a string (I’m not sure on why this method is here or why it is needed at all since you’re only using it from the Form method helper – more about this on future posts).

There are also another couple of internal methods:

  • GetModelAttemptedValue: method used for getting a value from the ModelState dictionary available from the ViewData property (if I recall it correctly,ModelState was introduced in preview 5 for helping in validation of form items – more  about this on a future post);
  • FindPartialView: auxiliary method used for getting a reference to a view (used by the RenderPartialinternal method for getting a reference to an IView object that is responsible for rendering the HTML sent back to the client);
  • RenderPartialInternal: used internally by the views for rendering partial views (check this post for more info).

And that’s all you have defined on the body of the class. There’s a lot more (under the form of extension methods),but we’ll leave it for a future post. Keep tuned!

Nov 25

Subcontrollers and caching on ASP.NET MVC

Posted in ASP.NET, MVC       Comments Off on Subcontrollers and caching on ASP.NET MVC

I’ve just read two interesting posts by Steve Sanderson which show how to add these features to the current release of ASP.NET MVC. Really interesting, if you ask me…

Oct 17

ASP.NET MVC beta is out

Posted in ASP.NET, MVC       Comments Off on ASP.NET MVC beta is out

Check Scott Gu’s post for all the details. I think it’s time to go back and pick where I left in the MVC series…

Oct 04

Protected: RouteValueDictionary: abuse or elegance?

Posted in ASP.NET, C#, MVC       Comments Off on Protected: RouteValueDictionary: abuse or elegance?

This content is password protected. To view it please enter your password below:

Sep 28

JQuery shipping with VS

Posted in ASP.NET, JQuery       Comments Off on JQuery shipping with VS

I”ve just read on Scott”s blog that JQuery is going to be shipped with VS. This is simply fantastic! I”ve been a fan of JQuery for some time now. It”s impossible not like its amazing flexibility and simplicity…and now we”ll have intellisense on VS and it looks like the future client side controls of ASP.NET AJAX (including the AJAX toolkit) will be written over it.

This is just great and I think that it”s a good move by MS (reusing instead of trying to build something when there”s a great product out there) that should also be followed with other similar projects…

Sep 23

The MVC platform – the UrlHelper class

Posted in ASP.NET, MVC       Comments Off on The MVC platform – the UrlHelper class

Today we’re going to start looking at the “famous” (well, most of the time I call then infamous, but the one we’re looking today is cool) helper classes introduced by the MVC platform. We’re going to start with one of the most important ones: the UrlHelper class. As you’ve seen, you’re be able to access an instance of this class through the Url properties exposed by the ViewPage and ViewUserControl classes. In theses cases, you don’t need to worry about initializing the new class instance because those classes alredy have the code to do that.

You’ll use this class whenever you need to get the url for a specific controller’s action method. The class ends up using its RouteCollection property to give you that information. As you might expect, if you don’t initialize that property (which you really won’t, unless you have specific needs or are writing tests), it will end up using the RouteTable that gets built during the application start event.

You’ll find several interesting methods:

  • Action:  several overloads of this method which let you generate an url based on an action;
  • RouteUrl: several overloads that will return an url based on a specific route info. For instance, if you’ve named your routes (like I generally do), you can pick a route by name and get its url;
  • Content: used for getting the path to a specific resource. You can use this method and pass one of those “relative” urls (“~/something”) and you’ll get the correct url for that resource;
  • Encode: used for encoding an url;

Most of the time, you’ll end up using the Action or RouteUrl methods. Lets start with the Action method.

The simplest thing you can do is call that method and pass the name of an action method. Here’s the signature of that method:

public string Action(string actionName)

If you do that, you’ll end up getting an url based on a method found on the current controller (the current controller is found by calling the GetRequiredString over the RouteData object that is avaiable throught the ViewContext that was passed to the view). If the route associated with the method requires parameters,then you can specify those values by using one of the following overloads:

public string Action(string actionName,object values)
public string Action(string actionName, RouteValueDictionary valuesDictionary)

Do notice that with the 1st version you can pass ana nonymous object with the values you want to pass to the parameters used by your route.

You’re also able to use a different controller by using one of the following overloads:

public string Action(string actionName, string controllerName, object values)
public string Action(string actionName, string controllerName, RouteValueDictionary valuesDictionary)

And  if you’re really picky, you can still end up using another couple of overloads which let you specify the protocol (for instance, you might want to go into https!) and the hostname. In these cases, you’ll be wanting to use one of these:

public string Action(string actionName, string controllerName, object values, string protocol)
public string Action(string actionName, string controllerName, RouteValueDictionary valuesDictionary, string protocol, string hostName)

The RouteUrl method is really similar to this, but as I’ve said, with the available overloads you’re able to select a route by name. These method are really cool and you can use them whenever you need an url and you know the name of a route. This is probably the method I’ve used most times until now.

Before ending, one final note: don’t forget that the strings returned aren’t encoded. So, if you need to encode them pass them through the Encode method.

This is really a short post and I’m not putting any examples of using these methods here. If you think examples are a must, please let me know and I’ll put some here.

More to come on future posts. Keep tuned!