Steve Moseley

"To err is human. To really screw up takes a computer." - Dilbert

JQuery, Asp.Net MVC 2 Multi Project Areas and Other News Minutia

clock April 3, 2010 08:45 by author Steve

jQuery News

I know this nugget is a couple of weeks old now, but did anyone catch the news that Microsoft is throwing its support behind jQuery?

So it seems that if you have been using the Microsoft AJAX tools you are probably not going to be seeing much of an effort to improve those tools in the future. Not that it really matters, since it seems that most developers have abandon that toolset about a year ago, and with the emergance of MVC, they were becoming irrelevant anyway. Also, the earlier versions of the Microsoft AJax framework had performance problems under heavy load and although they have done a lot of work to make improvements, jQuery is still far and away much faster. Plus, when working with designers who are not Microsoft centric, jQuery built a bridge for the developer and designer to work together.

I have several examples on jQuery Ajax calls in case you are interested.

My first official large site using ASP.Net MVC 2

So this past month I started working on my first large MVC web application using MVC 2, and although I have been playing around with for more than a year now, I have learned a lot in the few months. The book that was really helpful was “Pro ASP.Net MVC” Framework by Steven Sanderson. I highly recommend it if you are getting started, but you might want to wait until the MVC 2 revision comes out. If you can't wait for the revision there is the eBook "Asp.Net MVC 2 In Action." This book is good in that it covers some more advanced topics like how to keep you controllers light. I think the two books together will get you well on the way to developing in ASP.Net MVC.

So far the only hang up I had was that I had set up my solution to incorporate multi project areas which was supported in the MVC 2 preview releases of Areas. However, when the RTM came out it was no longer supported. I searched and searched for solutions to my dilemma, but the only thing I could find was post by Jonathon who basically had the same experience I had, and a reference to an obscure message on a message board saying (by what appeared to be some one from the ASP Team) that it was not supported. To date, I haven't found any more formal post or article saying that was not the case.

I looked at trying the MvcContrib’s portable area alternative, and it’s a pretty nice approach, but I would like my views deployed to production as separate files and not as a resource file in a assembly, so I decided not go that route. I think for now, I am just going to include the areas in a single project and when the next version of MVC comes out—pull the different areas out into different projects then—if that is, they will have that feature in future releases.

TFS license for VS 2008

I heard this week, not from someone official, that once Visual Studio 2010 is released, they will also include Team Foundation Server for Visual Studio 2008 as a part of the MSDN license. That good news for me as I have been using the trial version for the past few weeks. I suppose the cool tool now is GIT so maybe I should take a look at that as well. At least for my VS 2010 stuff. My only thing is I am getting kind of tired of having to learn a new source control repository every year, there are other cooler things I could be learning, but I guess that is part of the job.



MVC 2 Strongly Typed HTML Helper and Enhanced Validation Sample

clock March 13, 2010 09:40 by author Steve

In lue of the off the official release of ASP.NET MVC 2 RTM, I decided I would put together a quick sample of the enhanced HTML.Helpers and validation controls.

I am going to use my sample event site where I will have a form so a user can search for information about a certain events. So when the Search page loads the Search action is fired return my strongly typed model. to the view.

   1: [HttpGet]
   2: public ViewResult Search(): public ViewResult Search()
   3: {
   4:     IList<EventsModel> result = _eventsService.GetEventList();
   5:     var viewModel = new EventSearchModel
   6:                         {
   7:                             EventList = new SelectList(result, "EventCode","EventName","Select Event")
   8:                         };
   9:     return View(viewModel);
  10: }

Nothing special here, although I did want to show how to load up a strongly typed drop down list because that hung me up for a little bit. So to that, I am going to pass back a SelectList to the view and my HTML helper should no how to load this.

So lets take a look at the mark up for the view.

   1: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
   2: Inherits="System.Web.Mvc.ViewPage<EventsSample.Models.EventSearchModel>" %>
   3:  
   4: <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   5:     Search
   6: </asp:Content>
   7:  
   8: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   9:  
  10:     <h2>Search for Events</h2>
  11:  
  12:     <% using (Html.BeginForm("Search","Events")) {%>
  13:         <%= Html.ValidationSummary(true) %>
  14:         
  15:         <fieldset>
  16:             <legend>Fields</legend>
  17:             
  18:             <div class="editor-label">
  19:                 <%= Html.LabelFor(model => model.EventNumber) %>
  20:             </div>
  21:             <div class="editor-field">
  22:                 <%= Html.TextBoxFor(model => model.EventNumber) %>
  23:                 <%= Html.ValidationMessageFor(model => model.EventNumber) %>
  24:             </div>
  25:             
  26:             <div class="editor-label">
  27:                 <%= Html.LabelFor(model => model.GuestLastName) %>
  28:             </div>
  29:             <div class="editor-field">
  30:                 <%= Html.TextBoxFor(model => model.GuestLastName) %>
  31:                 <%= Html.ValidationMessageFor(model => model.GuestLastName) %>
  32:             </div>
  33:             
  34:             <div class="editor-label">
  35:                 <%= Html.LabelFor(model => model.EventName) %>
  36:             </div>
  37:             <div class="editor-field">
  38:                 <%= Html.DropDownListFor(model => model.EventName, Model.EventList,"Select Event") %>
  39:                 <%= Html.ValidationMessageFor(model => model.EventName) %>
  40:             </div>
  41:             
  42:             <p>
  43:                 <input type="submit" value="Save" />
  44:             </p>
  45:         </fieldset>
  46:  
  47:     <% } %>
  48:  
  49:     <div>
  50:         <%= Html.ActionLink("Back to List", "Index") %>
  51:     </div>
  52:  
  53: </asp:Content>

 

A nice feature is the scaffolding that MVC has to generate code. I simply right clicked inside my Search() action, inside the EventsController and selected “Add View” and then I selected my strongly typed object that I wanted to pass to the view and also selected that I wanted the content type be “Edit”. With that the aspx page was completely generated, although I did have to go back in and change the textbox for the Event Names to a drop down list of the names to select from.

The new feature with MVC 2 are the strongly typed HTML helpers. So now, my textboxes, drop down list, and validation helpers are all strongly typed to my model.  This features gives you the benefits of intellisense and also makes it easier to debug. “The Gu” has a great post about the feature in case you want more details. The DropDownListFor function to generate the drop down list was a little tricky for me. You first need to use a Lanbda expression to pass in the property you want the selected value assigned to in your model, and then you need to pass in the list directly from the model.

Validations

To validate the form, you can use the strongly type validation HTML helpers which will inspect your model and return errors if the validation fails. The definitions of these rules are set directly on the Model itself so lets take a look.

   1: using System.ComponentModel.DataAnnotations;
   2: using System.Web.Mvc;
   3:  
   4: namespace EventsSample.Models
   5: {
   6:     public class EventSearchModel
   7:     {
   8:         [Required(ErrorMessage = "Please enter the event number.")]
   9:         [RegularExpression(@"\w{6}", 
  10:             ErrorMessage = "The Event Number must be 6 letters and/or numbers.")]
  11:         public string EventNumber { get; set; }
  12:  
  13:         [Required(ErrorMessage = "Please enter the guest's last name.")]
  14:         [RegularExpression(@"^[A-Za-zÀ-ÖØ-öø-ÿ1-9 '\-\.]{1,22}$", 
  15:             ErrorMessage = "The gueest's last name must 1 to 20 characters.")]
  16:         public string GuestLastName { get; set; }
  17:  
  18:         public string EventName { get; set; }
  19:         public SelectList EventList { get; set; }
  20:     }
  21: }

Pretty cool!

Okay, the only thing left to do is perform the validation in the POST action.

   1: [HttpPost]
   2: public ViewResult Search(EventSearchModel eventSearchModel)
   3: {
   4:     if (ModelState.IsValid) return View("SearchResults");
   5:     else
   6:     {
   7:          IList<EventsModel> result = _eventsService.GetEventList();
   8:         eventSearchModel.EventList = new SelectList(result, "EVentCode","EventName");
   9:  
  10:         return View(eventSearchModel);
  11:     }
  12: }
  13:     }

 

If the form entries are valid, here I am simply displaying the SearchResult, but in a real world sample I would also go out get the results first. You get the idea though. In my case, when the form is not valid, I also had to reload my SelectList with the event names before I loaded the page again. Remember this is MVC, no _VieState here :)

So that’s it. Now my form is validating the data and when it fails it looks like this.

response



Spark View Engine – Render Partial While Passing the Model

clock January 5, 2010 15:31 by author steve

Just a quick follow up on my previous post specifically about rendering partial views using the Spark View Engine.  If you want to use a partial view and you also want to pass it a model, you just create parameter and pass the model in that parameter.

 

As I stated, the convention for the shared content is to create a file in the “Shared” view directory and prefix the file with the “_”.

 

For example:

I have created a post list partial file and I am going to call it from my “Index” view in the “Home” folder.

renderpartialsamp1

 

In the HomeController class, the Index action is just returning 10 items in a IList collection.

   1: public ActionResult Index()
   2: {
   3:     IList<PostDto> items = _postService.GetMostRecentPosts();
   4:  
   5:     ViewData["BasicPosts"] = items;
   6:     return View();
   7: }

Next, my Index view passes the collection of posts to the partial control.  The Index.spark file has the following code.

   1: <viewdata BasicPosts="IList<PostDto>">
   2:  
   3:  
   4: <postList posts="BasicPosts" />

 

Now the model is in the partial file and I can do with it what ever I want. In this example, the _postList.spark file has the following code that loops through the collection of posts and displays the “Title”.

   1: <ul>
   2: <for each="var post in posts">
   3:     <li>${post.Title}</li>
   4: </for>
   5: </ul>

 

The above sample produces this partial view.

partialResult



Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Sign in