ASPHostCentral.com ASP.NET MVC Hosting BLOG

All about ASP.NET MVC 4.0 Hosting, ASP.NET MVC 3.0 Hosting and ASP.NET MVC Hosting articles

ASP.NET MVC 3 Hosting :: Using an MVC PartialView With jQuery Templates Plugin

clock November 20, 2011 14:59 by author darwin

The other day I was talking some fellow developers about web architecture techniques. I brought up the use of jQuery templates instead of another proposed technique. A case was made the template plugin was not good for progressive enhancement. The objection was it forces you to maintain two separate HTML instances to render the same content. One instance for the initial server-side rendering and one for the client-side template. I knew this was not the case, so today I will show how to execute progressive enhancement while using ASP.NET MVC partial views.

There are two things you need to leverage to make this work. First, the model you are using should only use string properties. This is a bit unorthodox, but remember in the world of Model-View-Controller or MVVM, SOA, you tend to map objects between layers so they conform to their intended use.

The Contact entity now contains only string properties:

public class Contact {

    public string FirstName {get; set; }
    public string LastName {get; set; }
    public string PhoneNumber {get; set; }
    public string Street {get; set; }
    public string City {get; set; }
    public string State {get; set; }
    public string PostalCode {get; set; }

}


I know some of you are freaking out, but calm down. You can simply transform these values to the types you actually need in you application’s natural pipeline. As for validation, not doing in this little layer. I ultimately do validation on the client for UX purposes and for real in the business layer.

Now in your controller, I am just going to use HomeController today, you need to add a new View called ContactForm. It needs to have the
ChildActionOnly attribute applied.

[ChildActionOnly]
public ActionResult ContactForm() {


    return PartialView();

}


To make this work I need to add some code and parameters. The ContactForm partial view’s primary purpose is to render the desired contact, an empty new contact or the contact merge fields for the jQuery template plugin. I have added two parameters to the controller, Id and newContact. These are used to trigger the correct Contact object values.

[ChildActionOnly]
public ActionResult ContactForm(string Id, string newContact) {
   
    if (!string.IsNullOrEmpty(Id)) {
        ViewBag.Contact = contactServiceManager.GetContact(Id); ;
    } else {

        if (string.IsNullOrEmpty(newContact)) {

            ViewBag.Contact = new Contact()
            {
                ContactId = "${ContactId}",
                FirstName = "${FirstName}",
                LastName = "${LastName}",
                Business = "${Business}",
                Address1 = "${Address1}",
                Address2 = "${Address2}",
                City = "${City}",
                State = "${State}",
                PostalCode = "${PostalCode}",
                PhoneNumber = "${PhoneNumber}",
                EMail = "${EMail}",
                Comment = "${Comment}",
            };
       
        } else {

            ViewBag.Contact = new Contact();

        }

    }
 
    return PartialView("ContactForm");
}


The controller now checks the input parameters and creates a Contact object with the desired values. If there is an Id value it tries to retrieve the contact from the business layer. If not it checks to see if an empty Contact or a merge field Contact object is needed. 

The corresponding View is pretty straight forward. It simply fills the value of each INPUT tag with the appropriate values.

<div id="ContactEditForm">
  @using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
   
<input type="hidden" name="Id" id="Id" value="@ViewBag.Contact.ContactId" />
   
<fieldset class="span-1">
     
<legend>@ViewBag.Contact.FirstName @ViewBag.Contact.LastName</legend>
     
<ul>
       
<li>
         
<label for="FirstName">
            First Name
</label><input id="FirstName" name="FirstName"
             
class="" value="@ViewBag.Contact.FirstName" /></li>
       
<li>
         
<label for="LastName">
            Last Name
</label><input id="LastName" name="LastName"
             
class="" value="@ViewBag.Contact.LastName" /></li>
       
<li>
         
<label for="Business">
            Business
</label><input id="Business" name="Business"
             
class="" value="@ViewBag.Contact.Business" /></li>
       
<li>
         
<label for="Address1">
            Address1
</label><input id="Address1" name="Address1"
             
class="" value="@ViewBag.Contact.Address1" /></li>
       
<li>
         
<label for="Address2">
            Address2
</label><input id="Address2" name="Address2"
              
class="" value="@ViewBag.Contact.Address2" /></li>
       
<li>
         
<label for="City">
            City
</label><input id="City" name="City"
             
class="" value="@ViewBag.Contact.City" /></li>
       
<li>
         
<label for="State">
            State
</label><input id="State" name="State"  
           
class="" value="@ViewBag.Contact.State" /></li>
       
<li>
         
<label for="PostalCode">
            Postal Code
</label><input id="PostalCode"
           
name="PostalCode" class="" value="@ViewBag.Contact.PostalCode" /></li>
       
<li>
         
<label for="PhoneNumber">
            Phone Number
</label><input id="PhoneNumber"
           
name="PhoneNumber" class="" value="@ViewBag.Contact.PhoneNumber" /></li>
       
<li>
         
<label for="EMail">
            E-Mail
</label><input id="EMail" name="EMail"
           
class="" value="@ViewBag.Contact.EMail" /></li>
       
<li>
         
<label for="Comment">
            Comment
</label><input id="Comment"
           
name="Comment" class="" value="@ViewBag.Contact.Comment" /></li>
       
<li>
         
<ul class="btn-List">
           
<li>
             
<button id="CancelButton" class="btn"
             
text="Cancel" type='button' tabindex="199">
                Cancel
</button>
           
</li>
           
<li>
             
<button id="SaveButton" class="btn default"
             
type='submit' tabindex="198">
                Save
</button>
           
</li>
         
</ul>
       
</li>
     
</ul>
   
</fieldset>
  }
</div>


So the way I like to do a Master List/Detail UX is to list the records in a table and display a dialog for editing purposes. But let’s say you have a user fixated on the great JavaScript scare of 1995 and has it disabled. In this scenario the edit link will not display the edit dialog, but instead take them to the edit page. 

On my Master page, the Index view in this example, the following code adds the ContactForm partial view content. It creates the jQuery Template plugin template needed to render the edit dialog.

<script id="EditFormTemplate" type="text/html">
 @{Html.RenderAction("ContactForm", new { Id = "", newContact = "" });}
 </script>


Now in the actual Edit view the following code will simply render the form in the desired format if JavaScript is turned off or someone actually does a direct link to the form.

@{Html.Action("ContactForm", new { Id = "", newContact = "" });}

Whew!!! That’s a lot to digest and we are not done! 

As far as opening the edit dialog and using the jQuery template plugin to generate the input form, the following jQuery code intercepts a click on all edit links, merges the Contact object and appends it to the dialog. If you are not familiar with the
jQueryUI dialog widget there are various examples on the web. The documentation is pretty complete as well. As for the jQuery Templates plugin you can start with the source code page and go from there. I know I really need to blog more about them and I will, I will….

$(".edit-link").click(function (e) {

  e.preventDefault();

  var jqxhr = $.ajax({
    url: GetRootUrl() + "Home/Contact?Id=" + $(this).attr("Id")
  })
            .success(function (result) {

              contact = result;

              $("#EditFormTemplate")
                        .tmpl(result)
                                .appendTo("#contactDlg");

              $("#contactDlg").dialog('open');

            })
            .error(function (qXHR, textStatus, errorThrown) {
              alert("ack! an error!\r\n" + textStatus + " " + errorThrown);
            });

});


All right, that just about does it for the core code that drives this solution. Seeing is believing. (Disclaimer, I use a pretty bad random content generator to give me some dummy data, so excuse that, it’s just placeholder to me).





New Dialog (using the same code as the Edit Dialog BTW)



Edit page, using the same ContactForm partial view.

If you are using ASP.NET WebForms you can easily translate this technique using Custom Controls (.ascx) instead of Partial Views.


So this is my quick and dirty first hack at solving a very real problem. I am sure I will improve and refine this over the coming months. Since I am just now getting into MVC I am also sure I made some faux pas with that too, but again it works and can be improved upon.

Currently rated 1.7 by 140 people

  • Currently 1.735714/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: WebGrid in ASP.Net MVC3 Razor with Entity Framework

clock November 17, 2011 15:06 by author darwin

Hello, today I will talk about WebGrid in ASP.NET MVC 3 Razor. Yesterday, I talked much about ASP.NET MVC 4 and now back to ASP.NET MVC 3 again. J

OK, let’s start it, don’t waste our time.

1. Create a new ASP.Net MVC 3 application with an empty web application. While creating the project check the radio button "UnitTest".

2. Now under the "Model" folder create two classes.



3. Now in the Blog Class copy the following code:

public class Blog
    {
       
        [Key]      
        public int BlogId { get; set; }

        [Required(ErrorMessage = "BlogName is required")]
        public string BlogName { get; set; }

        [Required(ErrorMessage = "Description is required")]
        [StringLength(120, ErrorMessage = "Description Name Not exceed more than 120 words")]
        public string Description { get; set; }
        public string Body { get; set; }

        public virtual  List<Comments > Comments_List { get; set; }

    }

See here is the validation of each property. And also hold the list of comments. That means 1 blog contains many posts. So that is a one to many relationship.

The "Virtual" keywords means it will make the relationship.

4. Now in the Comments class write the following code:

public class Comments
    {
        [Key ]
        public int CommentId { get; set; }
          public string Comment { get; set; }
        //[ForeignKey]
          public int BlogId { get; set; }
          public virtual Blog Blog { get; set; }
 
    }


See here we also have the object reference of the "blog" class. Before that I have used the virtual key word.

5. Create a "DatabaseContext" folder under the project. After that create a class named "BlogDbContext.cs" under the folder. This class is an entity class.

6. Now make a reference for the Entity Framework by clicking "Add Reference" under the project.



In my project I had already provided the dll. Without this dll the table cannot be created in the database by object class mapping.

Now paste the following code into the "BlogDbContext" class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using blogmvc3.Models;

namespace blogmvc3.DatabaseContext
{
   
public class BlogDbContext:DbContext
    {
       
public DbSet<Blog> Blog { get; set; }
       
public DbSet<Comments> Comments { get; set; }
    }
}

See here in the Dbset we are passing a blog class and a comments class. The Dbset will create a table automatically with a relation in the database.

The Namespace "System.Data.Entity" is very important for that.

7. Now we have to configure the "web.config" file for the connection string. The web.config file is under the Main Solution Project. Not the Project web.config file.



Now paste the following connection string into the web.config file.

<connectionStrings>

    <add name="BlogDBContext" connectionString="data source=.;Database=Blogdb;Trusted_Connection=true;" providerName="System.Data.SqlClient" />
  </
connectionStrings>



8. Now create a Controller Class named "HomeController" under the "ControllerFolder. After that check the "Add action for create.update,delete.." so it will automatically create the action mrthod in the Controller class.





9. Now in the "HomeController" Class first create an object of the "BlogDbContext" Class.

BlogDbContext _db = new BlogDbContext();

After that in the Index Method write the following code:

public ActionResult Index()
        {
            return View(_db.Comments .ToList ());
        }

10. Now create a master page in the Razor engine under the "shared" folder. Give it the name "_LayoutPage1.cshtml".

After that paste the following code there:

<!DOCTYPE html>

<html>
<
head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
   @* <script src="../../Scripts/jquery-ui-1.8.11.custom.min.js" type="text/javascript"></script>
    <link href="../../Content/jquery-ui-1.8.11.custom.css" rel="stylesheet" type="text/css" />
*@
</head>

<body>
    <div class="page">

        <div id="header">
            <div id="title">
                <h1>Blog Post</h1>
            </div>

            <div id="logindisplay">
                @*@Html.Partial("_LogOnPartial")*@
            </div>

            <div id="menucontainer">

                <ul id="menu">
                   @* <li>@html.actionlink("home", "index", "home")</li>*@
                    @*<li>@Html.ActionLink("About", "About", "Home")</li>*@
                   <li>@Html.ActionLink("home", "index", "home")</li>
                     <li>@Html.ActionLink("Article Post", "CreateLogin", "Article")</li>
                     @*<li>@Html.ActionLink("BookCab", "CreateLogin", "Cab")</li> *@
                </ul>

            </div>
             <script type="text/javascript"><!--                 mce: 0--></script>

        </div>

        <div id="main">
            @RenderBody()
            <div id="footer">
            </div>
        </div>
    </div>
</
body>
</
html>

11. Now go the "Home controller". Right-click the Index Method and add a view. It will look like:



Please check "Create Strongly-typed Views".

Choose Model Class "Comments" Under DropDown List.

Select "Scaffold Template" List. After that press the "Add" button. It will automatically create a view named "Index" under the "Home" folder.

12. See the Index View Engine will create code for the list view automatically.

Now delete all the code and replace it with the following code:

@model IEnumerable<blogmvc3.Models.Comments>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_LayoutPage1.cshtml";

}
@{
    var grid = new WebGrid(source: Model, canPage: true, defaultSort: "BlogName", rowsPerPage: 3, canSort: true); 
    }

<h2>Web grid</h2>
if (@Model != null ) 

 {    

  @grid.GetHtml(tableStyle:"grid",headerStyle: "head",  alternatingRowStyle: "alt",caption:"WebGrid"
           )
 
 }

<p>

    @Html.ActionLink("Create New", "Create")
</p>

Now see this code section what is written above.



See first we are creating the WebGrid and after that in the constructor parameter we are passing a different property argument such as paging property, sorting, and rows per page.

And in the second we are are calling the WebGrid by calling the "@Html.WebGrid" property. Here also we are passing a parameter for the WebGrid.

Now run the application; it will look like the following figure:



See here the BlogId and Comments are displaying in the WebGrid (marked with red). And the paging facility is also done (marked with black).

Currently rated 2.8 by 31 people

  • Currently 2.806452/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: How to Stream Files to Client in ASP.NET MVC 3

clock November 1, 2011 14:57 by author darwin

Streaming files to the client is very easy using ASP.NET MVC 3: The following code snippet shows an exemplary controller action "Download" that streams data to the client. If the client requests this action (e.g. by using the link [YOUR_CONTROLLER]/Download) the browser will (depending on it's settings) start downloading the data or open the download dialog.
The first optional parameter mimeType (e.g. "image/jpeg" for jpeg images or "application/pdf" for pdf documents) defines the HTTP header Content-type which is used by the browser to decide how to handle the data. The second optional parameter fileDownloadName defines the name of file the data should be saved to on the client's computer.

public ActionResult Download()
{
  var fileStream = [...];
  var mimeType = [...]; // optional
  var fileDownloadName = [...]; // optional
  return File(fileStream, mimeType, fileDownloadName);
}

Currently rated 2.7 by 6 people

  • Currently 2.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3.0 Hosting :: Getting your ASP.NET MVC Application to return 404 HTTP Status Code

clock August 25, 2011 17:05 by author Administrator

ASP.NET MVC3 includes a new class HttpNotFoundResult in  System.Web.Mvc namespace.

HttpNotFoundResult: Instance of HttpNotFoundResult class indicates to client(browser) that the requested resource was not found. It returns a 404 HTTP status code to the client. Generally we return 404 status code if a requested webpage is not available. In case of MVC applications we return 404 status code is in terms of resources, for example we are searching for particular user profile in the portal, if the user profile is not found, we can return 404.

How to return 404 status code from a MVC application?
First way is to instantiate HttpNotFoundResult class and return the object.

public ActionResult Index()
{
            var result = new HttpNotFoundResult();
            return result;
}


Next alternative is to makes use of HttpNotFound() helper method of the Controller class which returns the HttpNotFoundResult instance.

public ActionResult Index()
{
             return HttpNotFound();
}


we can return 404 along with custom status code description,using the overloded version of HttpNotFound(string statusDescription).

public ActionResult Index()
{
             return HttpNotFound("can not find requested resource");
}

Currently rated 1.5 by 70 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Working with ASP.NET MVC 3 WebGrid (get selected row)

clock July 25, 2011 18:51 by author Administrator

Every website has to display data and every website has a Grid control. In ASP.NET MVC 3 there’s the WebGrid, which is part of the Microsoft Web Helpers library. This can be downloaded through NuGet (formerly NuPack). NuGet is a free open source package manager that makes it easy for you to find, install, and use .NET libraries in your projects. One piece of functionality that is critical is reacting when the user selects an item in the WebGrid. This article will focus on finding out which row was selected, but also how to find out more about the data that is selected.

Before moving on, you need to download ASP.NET MVC 3. Click here to download and install them using the Microsoft Web Platform Installer.

Open studio 2010 and create a new ASP.NET MVC 3 Web Application (Razor) project. To focus on the answer, I’ve got a simple model as seen below.



Using the WebGrid, it’s easy to display this data to the user.



The first column is the key to making this work. @item.GetSelectLink outputs a HTML anchor tag with the row selected. This is passed as a QueryString, and the name of the QueryString is set by the selectionFieldName property set on the grid.



To find out what row is selected is just as easy. The WebGrid has a property called SelectedRow. This sets a reference to a GridViewRow object that represents the selected row in the control. When you combine this with the HasSelection property, you can get the selected row like this.



I’ve created a partial view called _Person.cshtml. The file begins with an underscore (_) because I don’t want this file called directly from the web. The second parameter is the data being passed into the partial view. The data in this instance is the selected row.



The partial view has then got access to all the data in the selected row. Nice and easy. Thanks Microsoft!

Currently rated 1.4 by 7 people

  • Currently 1.428571/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Working with Razor Syntax RenderSection, RenderBody and RenderPage

clock May 8, 2011 17:23 by author Administrator

Everybody knows Razor is the new view engine ASP.NET Web Pages, so we thought we could write about some Razor syntax you may not be aware of. The three methods we’ll be focusing on today are RenderBody, RenderPage and RenderSection. You’ll need to understand how each of these work if you want to get know the Razor syntax intimately. This code also works in WebMatrix if you're using it.

Before moving on, you need to download ASP.NET MVC 3.
Click here to download and install them using the Microsoft Web Platform Installer.

Open studio 2010 and create a new ASP.NET MVC 3 Web Application (Razor) project. Now it's time to start coding! we’ll begin with the RenderBody method.

RenderBody

The RenderBody method resides in the master page, or in Razor this is commonly referred to as the Layout page. There can only be one RenderBody method per Layout page. If you’re from Web Forms world, the easiest way to think of RenderBody is it’s like the ContentPlaceHolder server control. The RenderBody method indicates where view templates that are based on this master layout file should “fill in” the body content.



RenderPage

Layout pages can also contain content that can be filled by other pages on disk. This is achieved by using the RenderPage method. This method takes either one or two parameters. The first is the physical location of the file, the second is an optional array of objects that can be passed into the page. Add a new cshtml file to the Shared folder and call it _Header.cshtml. We've prefixed this file with an underscore because we don't want this file to be called outside of RenderPage. By default, ASP.NET will not serve pages beginning with an underscore. Here's the code we’re adding to the _Header.cshtml page.

<h1>Header Here</h1>

And to use this in the layout, it's as easy as this.



RenderSection

Layout pages also have the concept of sections. A layout page can only contain one RenderBody method, but can have multiple sections. To create a section you use the RenderSection method. The difference between RenderSection and RenderPage is RenderPage reads the content from a file, whereas RenderSection runs code blocks you define in your content pages. The following code illustrates how to render a footer section.


RenderSection expects one parameter and that is the name of the section. If you don’t provide that, an exception will be thrown. Views can add data to sections by using the following code.


If you ran the website now it’ll run without error. If on the other hand you don’t include the section footer in the view, you’ll get an error.


That’s because by default, sections are mandatory. To make sections optional, just add the second parameter, which is a Boolean value.


Now things will run just fine.

These three methods you will use time and time again when you're using the Razor view engine. This code works both for ASP.NET MVC 3 and also WebMatrix. Have fun!

      

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Analyzing AllowHtml Attribute in ASP.NET MVC 3.0

clock March 31, 2011 15:10 by author Administrator

Let's say we are creating a simple form in our ASP.NET MVC 3 web application and there is a Body field on the form where we want to allow HTML Tags.

If we do not disable request validation in some manner for this Body field, we will get the dreaded error - A potentially dangerous Request.Form value was detected from the client (Body = "<br>").


Request validation is a good thing since it keeps people from injecting script tags in our application for Cross-Site Scripting ( XSS ) attacks. However, in this case we want to disable request validation on the Body Field so we can put HTML in the body of our blog posts.

ValidateInput Attribute

In ASP.NET MVC 2 we used the ValidateInput Attribute on the action to disable request validation for the entire request

The downfall of this approach is that the ValidateInputAttribute disables request validation on all model properties, and we just want to disable request validation on a single property, called Body.

AllowHtmlAttribute in ASP.NET MVC 3

In ASP.NET MVC 3 we now have a property attribute that we can include on model properties to disable request validation on a property by property basis, called AllowHtmlAttribute. Instead of using the ValidateInputAttribute on the action, we turn off request validation just on Body by adding the [AllowHtml] Attribute to it:


This allows HTML for the Body Property, but does not allow HTML for the Title Property, which is what we want.

[Note: Briefly in ASP.NET MVC 3, before it was released, there existed a SkipRequestValidationAttribute. It no longer exists and has been renamed to AllowHtmlAttribute.]

   

Currently rated 1.5 by 4 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC Hosting :: Working with Custom Authorisation in ASP.NET MVC Framework

clock March 30, 2011 16:20 by author Administrator

The whole advantage with MVC over webforms is extensibility at every point. Extensibility, Extensibility, Extensibility.

Authorization is a very important and every web project has there own needs and requirements. Full customisation is paramount.

Here I will show you a simple way to customise your authorization.

In MVC attributes are used to protect a controller method, so we to get started all we need to do is inherit from the AuthorizeAttribute class.

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            string[] users = Users.Split(',');
            if (!httpContext.User.Identity.IsAuthenticated)
                return false;
            if (users.Length > 0 &&
                !users.Contains(httpContext.User.Identity.Name,
                    StringComparer.OrdinalIgnoreCase))
                return false;
            return true;
        }
    }

This is the basics. We can put any logic we like in here and all we have to do is return false if for whatever reason the user should not be authorized. Then all you need to do is decorate the controller method with the new attribute as below.

    [CustomAuthorize]
    public ActionResult Index()
    {
        return View();
    }

From this simple example we can expand it with custom Roles.

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        // the "new" must be used here because we are hiding
        // the Roles property on the underlying class
        public new SiteRoles Roles;
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");
            string[] users = Users.Split(',');
            if (!httpContext.User.Identity.IsAuthenticated)
                return false;
            SiteRoles role = (SiteRoles)httpContext.Session["role"];

            if (Roles != 0 && ((Roles & role) != role))
                return false;
            return true;
        }
    }

Where the SiteRoles class is defined as below.

    [Serializable]
    [Flags]
    public enum SiteRoles
    {
        User = 1 << 0,
        Admin = 1 << 1,
        Helpdesk = 1 << 2
    }

This can then be used be used as follows.
    [CustomAuthorize(Roles=SiteRoles.Admin|SiteRoles.HelpDesk)]
    public ActionResult Index()
    {
        return View();
    }

This will only allow the Admin and the Helpdesk Role access to the Index controller. If you don’t belong to one of these roles then you will be sent to the Login page.

The possibilities are really endless.

Happy coding.

Currently rated 2.1 by 12 people

  • Currently 2.083333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3.0 Hosting :: ASP.NET MVC 3.0 Validation and IValidatableObject

clock March 27, 2011 19:04 by author Administrator

I was working with ASP.NET MVC 3 validation today and was tickled to learn of the support for IValidatableObject. I mainly like to use the Enterprise Library Validation Application Block in my projects, but System.ComponentModel.DataAnnotations has come a long way in .NET Framework 4.

[Aside: Note in the following post I interchange “object“, “model“, and “self” validation.] IValidatableObject for Self Validation

For those of you who are familiar with Enterprise Library, you know it has two attributes that can be used for self validation of an object: HasSelfValidation and SelfValidation. The idea here is that there is model validation that may need to happen as a whole in addition to just property validation. Or, maybe validation is so complex that you don't want to use validation attributes and just want to do all validation “manually“ in a method. Self validation in Enterprise Library gives you opportunity to do this.

In the DataAnnotations world, you get this same kind of model or object validation by implementing IValidatableObject. ASP.NET MVC 3 has built-in support for IValidatableObject, so after propery validation it will fire off object validation if your object implements IValidatableObject. An example is shown below:

  

In this trivial example, I test to see if ConfirmPassword equals Password during registration using IValidatableObject. If they don't match, this is a validation error and I return a ValidationResult with the error. Pretty simple stuff.

IValidatableObject Doesn't Always Fire

There is a gotcha here that may not be obvious. IValidatableObject in ASP.NET MVC 3 will not fire if there are property-level errors. As I mentioned, ASP.NET MVC 3 property validation occurs before object validation. If there are property errors, ASP.NET MVC 3 by design will not fire IValidatableObject so as not to return false positives ( thanks to Brad Wilson of Microsoft for confirming this today ). For those of you who use EnterpriseLibrary and Self Validation where Enterprise Library combines the results, this might not seem obvious and could trip you up. ASP.NET MVC 3 does not combine the results.

In the case above, if the username is not provided ( yet as shown is required ), but both password and confirm password are provided, IValidatableObject will not fire and confirm the passwords match. IValidatableObject will not fire until all property-level validators validate, regardless if the properties play a part in the self-validation or not.

Personally I don't find this an issue, but just wasn't expecting it with all my years of Enterprise Library Validation Application Block experience.

A Note About ValidationAttribute in .NET Framework 4

Just a quick note about ValidationAttribute in System.ComponentModel.DataAnnotations. The ValidationAttribute in .NET 4 has been beefed up with a ValidationContext Class being passed in the validate method. ValidationContext contains the entire object being validated during property validation. You could create a custom validation attribute and place it on Password or ConfirmPassword for property comparison. That is certainly a workaround if you want to return the password comparison error regardless if other non-involved properties do not validate.

 

Currently rated 3.0 by 4 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Working with ASP.NET MVC 3 RedirectPermanent syntax

clock March 23, 2011 16:42 by author Administrator

I am converting an ASP.NET WebForms website to ASP.NET MVC 3 for a client and by choice we are changing the URL structure as well. Because this may be a common situation, Microsoft introduced a new RedirectPermanent method on Response in ASP.NET 4.0.

If you take a peek at ASP.NET MVC 3, you will see new ActionResult Classes that do the same thing. You are probably familiar with Redirect, RedirectToAction, and RedirectToRoute, but now there are versions of these ActionResult Classes for permanent redirects: RedirectPermanent, RedirectToActionPermanent, and RedirectToRoutePermanent:  


Although out of the scope of this post, for search engine optimization benefits you will want to permanently redirect to the new location of a resource that has permanently moved by issuing an HTTP 301. The previous results only issue an HTTP 302, which means the resource has only temporarily moved.
  

Hope this helps.

Currently rated 1.5 by 26 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC Hosting

ASPHostCentral is a premier web hosting company where you will find low cost and reliable web hosting. We have supported the latest ASP.NET 4.5 hosting and ASP.NET MVC 4 hosting. We have supported the latest SQL Server 2012 Hosting and Windows Server 2012 Hosting too!


Sign in