European ASP.NET MVC Hosting

BLOG about Latest ASP.NET MVC Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET MVC 3 Hosting :: Configurable Action Filter Provider in ASP.NET MVC 3

clock August 23, 2011 04:49 by author Scott

In MVC 3 you can implement an IFilterProvider to create and feed action filters to the MVC runtime. Assuming you have the configuration classes in place from the last post, you can create a custom filter provider to add action filters to the MVC pipeline. 

public class ConfiguredFilterProvider : IfilterProvider
{
    public IEnumerable<Filter> GetFilters(
        ControllerContext controllerContext,
        ActionDescriptor actionDescriptor)
    {
        var filters = FiltersSettings.Settings.Filters;
        foreach (var filter in filters.Cast<FilterAction>())
        {
            var filterType = Type.GetType(filter.Type);
            yield return new Filter(
                    Activator.CreateInstance(filterType),
                    FilterScope.Global, order:null         
                );
        }
    }
}

Notice a filter provider receives context parameters it can use to determine if it should create a filter, or not. In this case we are creating global filters from whatever we find in the web.config file, so the parameters are left untouched.

To plug your filter provider into the MVC runtime, you'll need to execute a bit of code during application start up:

FilterProviders.Providers.Add(new ConfiguredFilterProvider());



European ASP.NET MVC 3 Hosting :: Configurable Global Action Filters for ASP.NET MVC 3

clock August 22, 2011 06:13 by author Scott

ASP.NET MVC 3.0 introduces global action filters - an easy way to apply an action filter to every action in an MVC application. All you need to do is register the filters during application startup:

protected void Application_Start()
{
    ...

    GlobalFilters.Filters.Add(new HandleErrorAttribute());
    GlobalFilters.Filters.Add(new FooFilter());
    GlobalFilters.Filters.Add(new BarFilter());
    ...
}

But what if you wanted to add (or remove) filters through configuration?

<configSections>
  <section name="filters"
           type="ConfigurableFilters.FiltersSettings, AssemblyName "/>
</configSections>
...
<filters>
  <add type="System.Web.Mvc.HandleErrorAttribute, System.Web.Mvc..." />
  <add type="ConfigurableFilters.BarFilter, AssemblyName" />
  <add type="ConfigurableFilters.FooFilter, AssemblyName" />
</filters>

In that case you'll need a ConfigurationElement.

public class FilterAction : ConfigurationElement
{
    [ConfigurationProperty("type", IsRequired = true, IsKey = true)]
    public string Type
    {
        get { return base["type"] as string; }
        set { base["type"] = value; }
    }
}

And a ConfigurationElementCollection.

public class FilterActionCollection : ConfigurationElementCollection
{      
    protected override ConfigurationElement CreateNewElement()
    {
        return new FilterAction();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {           
        return ((FilterAction) element).Type;
    }
}

And a ConfigurationSection

public class FiltersSettings : ConfigurationSection
{
    public static FiltersSettings Settings
    {
        get
        {
            var section = ConfigurationManager.GetSection("filters")
                          as FiltersSettings;
            return section ?? new FiltersSettings();               
        }
    }

    [ConfigurationProperty("", IsDefaultCollection = true)]
    public FilterActionCollection Filters
    {
        get
        {
            return base[_filtersProperty] as FilterActionCollection;
        }
        set
        {
            base[_filtersProperty] = value;
        }
    }

    private readonly ConfigurationProperty _filtersProperty =
        new ConfigurationProperty(
            null, typeof (FilterActionCollection), null,
            ConfigurationPropertyOptions.IsDefaultCollection);
}

One way to apply the configured filters is to use the following code during application startup:

var filters = FiltersSettings.Settings.Filters;
foreach (var filter in filters.Cast<FilterAction>())
{
    var filterType = Type.GetType(filter.Type);
    GlobalFilters.Filters.Add(Activator.CreateInstance(filterType));
}



European ASP.NET MVC 3 Hosting :: Cascading Dropdownlist in ASP.NET MVC 3 using jQuery

clock August 10, 2011 06:44 by author Scott

MVC 3 is becoming hugely popular thanks to Razor and the Helpers that make building web applications much easier. One of the common requirements in web development, both with web forms as well as MVC based development, is the cascading dropdownlist. Now, for Web Forms, we can use a variety of options viz. server side programming, jQuery or using the AJAX Control Toolkit’s cascading dropdownlist control for accomplishing this.

I saw a few samples on the internet that used the erstwhile Microsoft AJAX Library along with MVC and also few more samples which used hard coded values for wiring up the cascading dropdown. I have built this sample using Database with 3 tables i.e. Cars, Makes & Colours.

To begin with, lets examine the Database – CascadeSample. It has 3 tables

1. Cars
2. Models
3. Colours

First, lets create our MVC 3 Application using “File – New Project – ASP.NET MVC 3 Web Application” give it a name “CascadingDropdownSample” and select the “Internet Application” and click ok. This would create the basic scaffolding structure with Membership API. We won’t need it though.

As always with MVC, lets build the Model by right click Models Folder – Add – New Item and search for ADO.NET Entity in the search box of the Dialog.

Chose the ADO.NET Entity Data Model Template and give it a name CarModel.edmx and click Add.

Choose the “Generate from Database” option and in the Next steps, connect to the CascadeSample database and select all the 3 tables and then finish the steps to generate the Entity Model. Our Entity Model is now ready.

Next step is to start wiring up the Controller Actions. For the purpose of this simple demo, lets just use the default HomeController.

Lets add using CascadingDropdownSample.Models; to the namespaces in the HomeController.

Lets add CascadeSampleEntities cse = new CascadeSampleEntities(); within the class

Lets add the following within the Index Action.

public ActionResult Index()
{

ViewBag.Cars = cse.Cars.ToList();
ViewBag.Models = cse.Models.ToList();
ViewBag.Colours = cse.Colours.ToList();
return View();
}
 


Lets switch to the View (ROOT – Views – Home – Index.cshtml) and edit it to look as follows:-

@model CascadingDropdownSample.Models.CascadeSampleEntities
@{
ViewBag.Title = "Home Page";
}

<h2>Cars</h2>
<p>
@Html.DropDownListFor(Model => Model.CarId, new SelectList(ViewBag.Cars as System.Collections.IEnumerable, "CarId", "CarName"),
"Select a Car", new { id = "ddlCars" })
</p>

When we run the page, we will get to see the List of cars in the dropdown.

For the next set of actions i.e. populating the Model and Colour, we need the following Methods.

private IList<Model> GetModels(int id)
{
return cse.Models.Where(m => m.CarId == id).ToList();
}

private IList<Colour> GetColours(int id)
{
return cse.Colours.Where(c => c.ColourId == id).ToList();
}

The next main thing we need is Action methods which can send a JSon Result for both Models and Colours.

To first get the Models by car, we add the following to the HomeController

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult LoadModelsByCar(string id)
{
var modelList = this.GetModels(Convert.ToInt32(id));

var modelData = modelList.Select(m => new SelectListItem()
{
Text = m.ModelName,
Value = m.ModelId.ToString(),

});

return Json(modelData, JsonRequestBehavior.AllowGet);
}
 


and to get the Colours for the various Models, we add

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult LoadColoursByModel(string id)
{
var colourList = this.GetColours(Convert.ToInt32(id));

var colourData = colourList.Select(c => new SelectListItem()
{
Text = c.ColourName,
Value = c.ColourId.ToString(),

});

return Json(colourData, JsonRequestBehavior.AllowGet);
}
 


Finally, we need to add the following jQuery handlers for the dropdownlist selection changed

<script type="text/javascript">
$(document).ready(function () {
$("#ddlCars").change(function () {
var idModel = $(this).val();
$.getJSON("/Home/LoadModelsByCar", { id: idModel },
function (carData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Model"
}));
$.each(carData, function (index, itemData) {

select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
$("#ddlModels").change(function () {
var idColour = $(this).val();
$.getJSON("/Home/LoadColoursByModel", { id: idColour },
function (modelData) {
var select = $("#ddlColours");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Colour"
}));
$.each(modelData, function (index, itemData) {

select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});

</script>

And then add the dropdowns for Model and Colour

<p>
@Html.DropDownListFor(Model => Model.Models, new SelectList(Enumerable.Empty<SelectListItem>(), "ModelId", "ModelName"),
"Select a Model", new { id = "ddlModels" })

</p>
<p>
@Html.DropDownListFor(Model => Model.Colours, new SelectList(Enumerable.Empty<SelectListItem>(), "ColourId", "ColourName"),
"Select a Colour", new { id = "ddlColours" })

</p>

And then, when we build and run we can get to choose the Car, Model and Make, a cascading dropdown built using jQuery and MVC 3.

You can download the scripts here.



European ASP.NET MVC 3 Hosting :: ASP.NET MVC 3 Render Partial View to String

clock August 5, 2011 07:48 by author Scott

You can see this post first ASP.NET MVC Render Partial View to String. This post shows how to implement a RenderPartialViewToString method. To avoid the need of a parent class for each controller that implements this (helper) method I decided to use the following extension methods:

/// <summary>
/// Controller extension class that adds controller methods
/// to render a partial view and return the result as string.
///
/// Based on http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial
view-to-string/

/// </summary>
public static class ControllerExtension
{ 

  /// <summary>
  /// Renders a (partial) view to string.
  /// </summary>
  /// <param name="controller">Controller to extend</param>
  /// <param name="viewName">(Partial) view to render</param>
  /// <returns>Rendered (partial) view as string</returns>
  public static string RenderPartialViewToString(this Controller controller, string viewName)
  {
    return controller.RenderPartialViewToString(viewName, null);
  } 

  /// <summary>
  /// Renders a (partial) view to string.
  /// </summary>
  /// <param name="controller">Controller to extend</param>
  /// <param name="viewName">(Partial) view to render</param>
  /// <param name="model">Model</param>
  /// <returns>Rendered (partial) view as string</returns>
  public static string RenderPartialViewToString(this Controller controller, string viewName, object model)
  {
    if (string.IsNullOrEmpty(viewName))
      viewName = controller.ControllerContext.RouteData.GetRequiredString("action"); 

      controller.ViewData.Model = model; 

      using (var sw = new StringWriter())
      {
        var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
        var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
        viewResult.View.Render(viewContext, sw); 

        return sw.GetStringBuilder().ToString();
      }
    } 

}

Using this extension methods my controller actions handling the AJAX requests look like this:

[HttpPost]
public ActionResult Update(int id, Model model)
{
  if (ModelState.IsValid)
  {
    // Update the database
    [...] 

    // Partial/FormUpdated contains a success message
    return Json(new Object[] { true, this.RenderPartialViewToString("Partial/FormUpdated", model) });
  } 

  // Partial/Form contains the form with all server-side validation errors
  return Json(new Object[] { false, this.RenderPartialViewToString("Partial/Form", model) });
}



European ASP.NET MVC 3 Hosting :: EditorTemplates in ASP.NET MVC 3

clock August 4, 2011 07:44 by author Scott

In this tutorial, I will show you how to use EditorTemplates in ASP.NET MVC 3.

1. Create the template

In this article, we create the file called “Address.cshtml”. And we place it into “Shared/EditorTemplate/” folder. You can preview it on the image below



2. Create model and controller

Model
: Person Class

public class Person
{
    public Person()
    {
        Name = "George";

        var newYork = new Address
                  {
                      City = "NY",
                      Country = "USA",
                      PostalCode = "10021",
                      Street = "34 Vosges street"
                  };

        var paris = new Address
                        {
                            City = "Paris",
                            Country = "France",
                            PostalCode = "75001",
                            Street = "13 Leclerc street"
                        };

        var bruxelles = new Address
                            {
                                City = "Bruxelles",
                                Country = "Belgium",
                                PostalCode = "65478",
                                Street = "01 Garden Street"
                            };

        Addresses = new List<Address> { newYork, paris, bruxelles };
    }

    public string Name { get; set; }
    public List<Address> Addresses { get; set; }
}

Model : Address Class

public class Address
{
    public string Street { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
}


Controler : PersonWithAddress

public class PersonWithAddressController : Controller

{
    public ActionResult Index()
    {
        return View(new Person());
    }
}

3. The View

Here, we strongly typed our View with our model (Person). (Of course it’s not mandatory to use strongly typed view if you want to use EditorTemplate). We want to be able to display the Person with all its addresses.


We call the Html helper EditorFor. For each Address object in the list, Razor will call the Address template.

@model MvcEditorTemplates.Models.Person
@{
    ViewBag.Title = "Person with Addresses";
}
<h2>Person</h2>
<p>
    @Html.LabelFor(model => model.Name)
    @Html.EditorFor(model => model.Name)
</p>   

<h2>Person Addresses</h2>
@Html.EditorFor(model => model.Addresses)

This is the preview



European ASP.NET MVC 3 Hosting :: Ajax in ASP.Net MVC 3

clock July 28, 2011 05:53 by author Scott

In asp.net web form application, if we need ajax service, we will need to create wcf services on server side to serve ajax calls, while in MVC web application(version 3), no wcf is needed, a controller will do.

Here are two examples (GET and POST) of how to use ajax in mvc application

Http Get example: ajax consumer in view

<script type="text/javascript">
  var user = {
                'id': 1
            };

    $.get(
                'home/getUser',
                user,
                function (data) {
                    alert(data.name);
                }

    );
</script>


Http Get example: ajax server in home controller

public class HomeController : Controller
{
    // data GET service
     public JsonResult getUser(int id)
     {

            User user = db.Users.where(u=>u.id==id)

            return Json(user,JsonRequestBehavior.AllowGet);
     }

}

A few points:


Controller must return JsonResult rather than ActionResult as a normal controller does as we would want the data to be returnd as json data, and it does not have a ‘d’ wrapper

JsonRequestBehavior.AllowGet must be set in Json()call, otherwise you will get:

500 internal server error with message like

This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet

You only need to set this parameter for GET and returning JSON array to avoid JSON hijacking, no need for POST requests.
Http POST example: ajax consumer in view


<script type="text/javascript">
var user={
            'name':’TheUser’,
            'age':30
        };

 $.post(
            'home/SaveUser',
            user,
            function (data) {
                if (data === true) {
                   alert('User is saved');
                }
                else {

                    alert('Failed to save the user');

                }
            },
            'json'
        );
</script>


Http POST example: ajax server in home controller

public class HomeController : Controller
{
    // data POST service
  [AcceptVerbs(HttpVerbs.Post)]
   public JsonResult SaveUser (string name, int age)
   {

        return Json(true);
    }
}

A few points:

Have to decorate the controller with ‘POST’

Datatype in $.post in example is set to json, but it is not necessary to be so, if you just pass data in fields rather than in complex object. When it is not set to json it will use application/x-www-form-urlencoded as a way to pass data in standard post.


Summary:
In asp.net MVC you can use controller as ajax server without having to use wcf, compared with wcf, no configuration is needed



European ASP.NET MVC Hosting :: ASP.NET MVC Client Side Validation With Dynamic Contents

clock July 27, 2011 08:14 by author Scott

Introduction:

There are lot of occasions when developers do not let the users to fill the complete form at once, instead developers use wizards steps to get the different information from users at different steps. For example, ASP.NET(Web Form) Wizard Control which allows the developers to easily create multi step user interface. But unlike traditional post back for every step, developers likes to use Ajax to show different wizards steps without a complete post back. Every wizard step includes different client side validation rules. In this article I will show you how to do the same task in ASP.NET MVC using the built-in client side validation libraries.

Description:

Let's create a sample application to allow the users to register them using two steps Ajax wizard form. In the first step users will fill thier own information and in second step user will fill their company information and third step just shows a Thank You message. First of all create a ASP.NET MVC application. Then just open HomeController.cs and add the following code,


public ActionResult CreateUser() 
{ 
   return View(); 
} 
[HttpPost] 
public ActionResult CreateUserPrevious(UserInformation u) 
{ 
   return View("CreateUserInformation", u); 
} 
[HttpPost] 
public ActionResult CreateUserInformation(UserInformation u) 
{ 
   if(ModelState.IsValid) 
       return View("CreateUserCompanyInformation"); 
   return View("CreateUserInformation"); 
} 
[HttpPost] 
public ActionResult CreateUserCompanyInformation(UserCompanyInformation uc, UserInformation ui) 
{ 
   if (ModelState.IsValid) 
       return Content("Thank you for submitting your information"); 
   return View("CreateUserCompanyInformation"); 
}

Next create a CreateUser view and add the following lines,


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ClientSideValidationWithDynamicContent.Models.UserInformation>" %> 
  <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
      CreateUser 
  </asp:Content> 
  <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
      <div id="dynamicData"> 
          <%Html.RenderPartial("CreateUserInformation"); %> 
      </div> 
  </asp:Content>

Next create a CreateUserInformation partial view and add the following lines,

       <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ClientSideValidationWithDynamicContent.Models.UserInformation>" %> 
       <% Html.EnableClientValidation(); %> 
       <%using (Html.BeginForm("CreateUserInformation", "Home")) 
       { %> 
       <table id="table1"> 
         <tr style="background-color:#E8EEF4;font-weight:bold"> 
            <td colspan="3" align="center"> 
                 User Information 
            </td> 
         </tr> 
          <tr> 
            <td> 
                 First Name 
            </td> 
            <td> 
                 <%=Html.TextBoxFor(a => a.FirstName)%> 
            </td> 
            <td> 
                 <%=Html.ValidationMessageFor(a => a.FirstName)%> 
          </td>            
      </tr> 
      <tr> 
          <td> 
                Last Name 
          </td> 
          <td> 
                <%=Html.TextBoxFor(a => a.LastName)%> 
          </td> 
          <td>  
                <%=Html.ValidationMessageFor(a => a.LastName)%> 
          </td>            
      </tr> 
      <tr>              <td> 
                Email 
          </td> 
          <td> 
                <%=Html.TextBoxFor(a => a.Email)%> 
          </td> 
          <td> 
                <%=Html.ValidationMessageFor(a => a.Email)%> 
          </td>            
      </tr>        

      <tr> 
          <td colspan="3" align="center"> 
                <input type="submit" name="userInformation" value="Next"/> 
          </td> 
      </tr> 
    </table> 
<%} %> 
<script type="text/javascript"> 
    Sys.Mvc.FormContext._Application_Load(); 
    $("#form0").submit(function (e) { 
        if (!Sys.Mvc.FormContext.getValidationForForm(this).validate('submit').length) { 
            $.post("/Home/CreateUserInformation",$(this).serialize(), function (data) { 
                $("#dynamicData").html(data); 
            }); 
        } 
        e.preventDefault(); 
   }); 
</script>

Next create a CreateUserCompanyInformation partial view and add the following lines,

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl     <ClientSideValidationWithDynamicContent.Models.UserCompanyInformation>" %> 
    <% Html.EnableClientValidation(); %>    
    <%using (Html.BeginForm("CreateUserCompanyInformation", "Home")) 
    { %> 
      <table id="table1"> 
        <tr style="background-color:#E8EEF4;font-weight:bold"> 
            <td colspan="3" align="center"> 
           User Company Information 
            </td> 
        </tr> 
        <tr> 
            <td> 
           Company Name 
            </td> 
            <td> 
                <%=Html.TextBoxFor(a => a.CompanyName)%> 
            </td> 
            <td> 
                <%=Html.ValidationMessageFor(a => a.CompanyName)%> 
            </td>            
        </tr> 
        <tr> 
            <td> 
           Company Address 
            </td> 
            <td> 
                <%=Html.TextBoxFor(a => a.CompanyAddress)%> 
            </td> 
            <td> 
                <%=Html.ValidationMessageFor(a => a.CompanyAddress)%> 
            </td>            
        </tr> 
        <tr> 
            <td> 
           Designation 
            </td> 
            <td> 
                <%=Html.TextBoxFor(a => a.Designation)%> 
            </td> 
            <td> 
                <%=Html.ValidationMessageFor(a => a.Designation)%> 
            </td>            
        </tr>       

        <tr> 
            <td colspan="3" align="center">                
                <input type="button" id="prevButton" value="Previous"/>   
                <input type="submit" name="userCompanyInformation"
value="Next"/> 

                <%=Html.Hidden("FirstName")%> 
                <%=Html.Hidden("LastName")%> 
                <%=Html.Hidden("Email")%> 
            </td> 
        </tr> 
        </table> 
       <%} %> 
    <script type="text/javascript"> 
       Sys.Mvc.FormContext._Application_Load(); 
       $("#prevButton").click(function () { 
          $.post("/Home/CreateUserPrevious", $("#form0").serialize(),
function (data) { 

               $("#dynamicData").html(data); 
           }); 
       }); 
       $("#form0").submit(function (e) { 
           if
(!Sys.Mvc.FormContext.getValidationForForm(this).validate('submit').length) { 

               $.post("/Home/CreateUserCompanyInformation",
$(this).serialize(), function (data) { 

                   $("#dynamicData").html(data); 
               }); 
           } 
           e.preventDefault(); 
       }); 
    </script>

Next create a new class file UserInformation.cs inside Model folder and add the following code,


public class UserInformation 
{ 
   public int Id { get; set; } 
   [Required(ErrorMessage = "First Name is required")] 
   [StringLength(10, ErrorMessage = "First Name max length is 10")] 
   public string FirstName { get; set; } 
   [Required(ErrorMessage = "Last Name is required")] 
   [StringLength(10, ErrorMessage = "Last Name max length is 10")] 
   public string LastName { get; set; } 
   [Required(ErrorMessage = "Email is required")] 
   [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Email Format is wrong")] 
   public string Email { get; set; } 
}

Next add the necessary script files in Site.Master,

<script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script> 
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script> 
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> 
<script src="../../Scripts/MicrosoftMvcValidation.debug.js" type="text/javascript"></script>

Now run the application and navigate to Home/CreateUser, you will find the following screen,



Just fill the user information form and click Next, you will find the following screen



Just fill the user company information form and click Next, you will find the following screen,



 Now just see what makes the client side validation possible with dynamic contents. First of all note that ASP.NET MVC will emits client side validation script only if you have Html.EnableClientValidation() (which internally sets ViewContext.ClientValidationEnabled = true) inside your view or partial view. Client side validation for dynamic contents will still not work unless you call Sys.Mvc.FormContext._Application_Load() function(which simply do some initialization) in your dynamic contents(partial view).


 Another very important point to note here is that dynamic contents includes a html form. This is necessary because ASP.NET MVC emits the validation script during MvcForm.Dispose method. Therefore if you do not have Html.BeginForm in your dynamic contents, no script will be emitted, due to which client side validation will not work.

 Another key point to note here is that client side validation is explicitly invoking using, (!Sys.Mvc.FormContext.getValidationForForm(this).validate('submit').length).  If the form is valid then I am just using jQuery.post to post the form to server asynchronously and get the dynamic contents and update the document. This is important to prevent the traditional postback because by default ASP.NET MVC client side validation library do a complete postback if the form is valid.

Summary:

 Ajax wizards form are very popular way to get and validate the user information using wizard steps. ASP.NET MVC has no exception. In this article I shows you how you can very easily enable client side validation for dynamic contents. I am also attaching a sample application. Hopefully you will again enjoy this



European ASP.NET MVC 3 Hosting :: Handling errors in ASP.NET MVC 3

clock July 25, 2011 08:15 by author Scott

With the arrival of ASP.NET MVC 3, it is very easy for us to handle errors in ASP.NET MVC.

The HandleErrorAttribute in ASP.NET MVC lets us specify how to handle an exception that is thrown by an action method. By default, when an action method with the HandleErrorAttribute throws an exception, MVC displays the Error view that is located in the ~/Views/Shared folder.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)


{


    filters.Add(new HandleErrorAttribute());

}


This filter automatically applies to any action method in any controller so that you don’t have to apply HandleErrorAttribute action level or controller level.

If user makes a request for web.config file (http://yourDomain.com/web.config), and we know that MVC restricts this request and throws an exception that is uncatchable by HandleErrorAttribute because HandleErrorAttribute just handles errors that are thrown by action methods. So for above case, traditional asp.net error window will be displayed.

Here is a diagram that show how HandleErrorAttribute works?



So how to handle errors that are not thrown by any action method means that errors those are unhandled or uncaught able by HandleErrorAttribute.

It’s simple, just create a new file ‘Error.aspx’ in the root of the project and update web.config file with this code snippet:

<customErrors mode="On" redirectMode="ResponseRewrite"


              defaultRedirect="Error.aspx" />

Now, whenever an error thrown by any action method, HandleErrorAttribute are asked to handle it and ~/Views/Shared/Error.aspx view will be displayed. In contrast, when an unhandled error will occur that is not thrown by any action method, this Error.aspx file will be displayed to end user.

If you want to know what unhandled error was and you want to be informed through email, it is simple, just do it:

// for Sending Error in Email


protected void Page_Load(object sender, EventArgs e)


{


   string subject = "An unhandled Error Message";


   string body = HttpContext.Current.Server


                     .GetLastError().ToString();


    subject.SendErrorMessage(body);


}


public static void SendErrorLive(this string subject,


string body)


{


    WebMail.From = “[email protected]”;


    WebMail.Password = “password”;


    WebMail.SmtpPort = 25;


    WebMail.SmtpServer = “smtp.live.com”;


    WebMail.UserName = “[email protected]”;


    WebMail.EnableSsl = true;


    WebMail.SmtpUseDefaultCredentials = false;


    WebMail.Send(“[email protected]”, subject, body);


}

Oh no, this technique is for Error.aspx but what for ~/Views/Shared/Error.cshtml?

By default, asp.net mvc passes HandleErrorInfo type to the Error.cshtml view. This type let us directly get error info as shown here:

@Model.Exception.Message

Or directly send email within the view:

@{Model.Exception.GetType().ToString()


.SendErrorMessage(Model.Exception.ToString());}

Now following errors are under your control:

1. Errors that are thrown by action methods [~/Views/Shared/Error.cshtml]
2. Any other kind of errors [Error.aspx]



European ASP.NET MVC 3 Hosting :: ASP.NET MVC3 Tools Update – Scaffolding with the Repository Pattern

clock July 8, 2011 08:28 by author Scott

In this post I’m going to show you how to use MvcScaffolding to add a new controller template to enable scaffolding with data access code that uses the Repository Pattern.

One of the new features is built in tooling support for scaffolding. The “Add Controller” Dialog box has been revamped to include a few new options.

As you can see there are much more options as compared to before. The scaffolding options are as follows:

- Template: Allow you to specificy what kind of controller you want to generate. Out of the box you get an empty controller (Just a class with no actions), Controller with actions and views using the Entity Framework code first, and controller with empty read/write actions.

- Model: This is the object that will be used for scaffolding strongly typed views, CRUD actions and data access.

- DataContext: By default this is an EF Code First class that inherits from DbContext. You can either select an existing context or have the scaffolding tools create a new one for you.

- Views: Select between ASPX and Razor. This is pretty much the same as the “Add New View” dialog box.

- Advanced Options include layout/master page settings and View script settings. Again, stuff that is also in the “Add New View” Dialog.



Scaffolding using the “Controller with read/write actions and views, using Entity Framework” is especially cool because it generates a controller, all associated views AND data access code for you. That’s right, all you need to do is create an model class and the scaffolder does the rest. How’s that for a productivity boost?


To test this I created a simple Product class which is defined as the following:

public class Product{
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}


Then I added a new controller with the following options:



The new tooling support created a new controller, all associated views and the data access code. That’s really cool, but let’s take a look at the controller code.

private ProductContext db = new ProductContext();
 //
// GET: /Product/
 public ViewResult Index()
{
return View(db.Products.ToList());
}


By default the scaffolding tools use the ProductContext object directly in the Controller. Many people don’t like this coupling (myself included) and prefer to use
the Repository Pattern. This allows us to abstract away our data access code behind a repository, making it easier to work with and later modify, if need be.

Well the good news is that the add controller dialog is extensible. You can add your own controller templates to enable data access using any technology mechanism you want.

I’m going to show you a way to get a repository option for EntityFramework to show up with very little work. All you need to do is install the MvcScaffolding NuGet Package.

Open the Package Manager Console and enter “Install-Package MvcScaffolding”:



Now right click on the controllers folder and select “Add”->”Controller”. We’re going to re-scaffold out our ProductController, associated views and data access code (WARNING: This will overwrite any changes you have made so be careful.)

Now take a look at the templates section and you should see new templates:



The last option let’s you scaffold out the entire thing and use repositories for data access. Go ahead and click “Add”. Check the checkboxes to allow the scaffolder to override existing items.

We can verify this by looking at our ProductController and we should see the following:

private readonly IProductRepository productRepository;

// If you are using Dependency Injection, you can delete the following constructor
public ProductController() : this(new ProductRepository()) { }
 public ProductController(IProductRepository productRepository) {
this.productRepository = productRepository;
}

//
// GET: /Product/
 public ViewResult Index(){
return View(productRepository.All);
}

Now the controller uses a repository instead of hard coding in the data access code. The repository itself uses EF Code First to do all the data access.



European ASP.NET MVC Hosting :: ASP.NET MVC Routing Tutorial

clock July 7, 2011 07:23 by author Scott

In this tutorial, you are introduced to an important feature of every ASP.NET MVC application called ASP.NET Routing. The ASP.NET Routing module is responsible for mapping incoming browser requests to particular MVC controller actions. By the end of this tutorial, you will understand how the standard route table maps requests to controller actions.

Using the Default Route Table

When you create a new ASP.NET MVC application, the application is already configured to use ASP.NET Routing. ASP.NET Routing is setup in two places.

First, ASP.NET Routing is enabled in your application's Web configuration file (Web.config file). There are four sections in the configuration file that are relevant to routing: the system.web.httpModules section, the system.web.httpHandlers section, the system.webserver.modules section, and the system.webserver.handlers section. Be careful not to delete these sections because without these sections routing will no longer work.

Second, and more importantly, a route table is created in the application's Global.asax file. The Global.asax file is a special file that contains event handlers for ASP.NET application lifecycle events. The route table is created during the Application Start event.

The file in Listing 1 contains the default Global.asax file for an ASP.NET MVC application.

Listing 1 - Global.asax.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication1
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

When an MVC application first starts, the Application_Start() method is called. This method, in turn, calls the RegisterRoutes() method. The RegisterRoutes() method creates the route table.

The default route table contains a single route (named Default). The Default route maps the first segment of a URL to a controller name, the second segment of a URL to a controller action, and the third segment to a parameter named id.

Imagine that you enter the following URL into your web browser's address bar:

/Home/Index/3

The Default route maps this URL to the following parameters:

controller = Home

action = Index

id = 3

When you request the URL /Home/Index/3, the following code is executed:

HomeController.Index(3)

The Default route includes defaults for all three parameters. If you don't supply a controller, then the controller parameter defaults to the value Home. If you don't supply an action, the action parameter defaults to the value Index. Finally, if you don't supply an id, the id parameter defaults to an empty string.

Let's look at a few examples of how the Default route maps URLs to controller actions. Imagine that you enter the following URL into your browser address bar:

/Home

Because of the Default route parameter defaults, entering this URL will cause the Index() method of the HomeController class in Listing 2 to be called.

Listing 2 - HomeController.cs

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index(string id)
        {
            return View();
        }
    }
}

In Listing 2, the HomeController class includes a method named Index() that accepts a single parameter named Id. The URL /Home causes the Index() method to be called with an empty string as the value of the Id parameter.

Because of the way that the MVC framework invokes controller actions, the URL /Home also matches the Index() method of the HomeController class in Listing 3.

Listing 3 - HomeController.cs (Index action with no parameter)

using System.Web.Mvc;


namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

The Index() method in Listing 3 does not accept any parameters. The URL /Home will cause this Index() method to be called. The URL /Home/Index/3 also invokes this method (the Id is ignored).

The URL /Home also matches the Index() method of the HomeController class in Listing 4.

Listing 4 - HomeController.cs (Index action with nullable parameter)

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index(int? id)
        {
            return View();
        }
    }
}

In Listing 4, the Index() method has one Integer parameter. Because the parameter is a nullable parameter (can have the value Null), the Index() can be called without raising an error.

Finally, invoking the Index() method in Listing 5 with the URL /Home causes an exception since the Id parameter is not a nullable parameter. If you attempt to invoke the Index() method then you get the error displayed in Figure 1.

Listing 5 - HomeController.cs (Index action with Id parameter)

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index(int id)
        {
            return View();
        }
    }
}



The URL /Home/Index/3, on the other hand, works just fine with the Index controller action in Listing 5. The request /Home/Index/3 causes the Index() method to be called with an Id parameter that has the value 3.

Summary

The goal of this tutorial was to provide you with a brief introduction to ASP.NET Routing. We examined the default route table that you get with a new ASP.NET MVC application. You learned how the default route maps URLs to controller actions. Hope the tutorial can help and give benefit for all of you.



About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in