European ASP.NET MVC 4 and MVC 5 Hosting

BLOG about ASP.NET MVC 3, ASP.NET MVC 4, and ASP.NET MVC 5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET MVC 3 Hosting :; ExtJS and ASP.NET MVC 3

clock September 21, 2011 07:10 by author Scott

This short tutorial will walk though the implementation of DataGrid using ExtJS 3.3.1 and ASP.NET MVC 3. In this tutorial I focus more on the integration of the front-end, so you will not find any database code. Whenever we deal with data we usually create, read/retrieve, update or delete them. ExtJS provides a great data grid component and the ability to perform CRUD operation with very little coding. I used JSON as data format in the example below.



Let’s start with the server-side by developing the data model and controller.

Controller:

public class ContactController : Controller 
{ 
    // 
    // GET: /Contact/ 
    public ActionResult Index() 
    { 
        return View(); 
    } 
    public JsonResult Load() 
    { 
        var contact = new List<Contact> { 
            new Contact("Smith","95746325","[email protected]"), 
            new Contact("Adam","87291034","[email protected]"), 
            new Contact("Eve","98271345","[email protected]"), 
            new Contact("Chun Li","81728312","[email protected]") 
        }; 
        return Json(new
        { 
            total = contact.Count, 
            data = contact, 
        }, JsonRequestBehavior.AllowGet); 
    } 
    [HttpPost] 
    public JsonResult Create(List<Contact> data) 
    { 
        //insert Create code 
        return Json(new
        { 
            data = new Contact(data[0].Name, data[0].Phone, data[0].Email), 
            success = true, 
            message = "Create method called successfully"
        }); 
    } 
    [HttpPost] 
    public JsonResult Update(List<Contact> data) 
    { 
        //insert Update code 
        return Json(new
        { 
            success = true, 
            message = "Update method called successfully"
        }); 
    } 
    [HttpPost] 
    public JsonResult Delete(List<string> data) 
    { 
        //insert Delete code 
        return Json(new
        { 
            success = true, 
            message = "Delete method called successfully"
        }); 
    } 
}

Data Model:

public class Contact 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string Phone { get; set; } 
    public string Email { get; set; } 
    public Contact(string pName, string pPhone, string pEmail) 
    { 
        this.Id = System.Guid.NewGuid().ToString(); 
        this.Name = pName; 
        this.Phone = pPhone; 
        this.Email = pEmail; 
    } 
    public Contact() { } 
}

ExtJS:

Now, you move on to the view and work on the ExtJS. First, you define the record type which matches the server-side object.

var Contact = Ext.data.Record.create([ 

    { 
        name: 'Id', 
        type: 'string'
    }, { 
        name: 'Name', 
        type: 'string'
    }, { 
        name: 'Phone', 
        type: 'string'
    }, { 
        name: 'Email', 
        type: 'string'
    } 
]);

Now you need to setup the Writer and Reader

var writer = new Ext.data.JsonWriter({ 

    encode: false, 
    listful: true, 
    writeAllFields: true
}); 
var reader = new Ext.data.JsonReader({ 
    totalProperty: 'total',
    successProperty: 'success', 
    idProperty: 'Id', 
    root: 'data', 
    messageProperty: 'message'  // <-- New "messageProperty" meta-data 
}, Contact);

Then, setup a proxy to define the connection to the controller.

var proxy = new Ext.data.HttpProxy({ 

   api: { 
       read: '/Contact/Load', 
       create: '/Contact/Create', 
       update: '/Contact/Update', 
       destroy: '/Contact/Delete'
   }, 
   headers: { 'Content-Type': 'application/json; charset=UTF-8' } 
});

Hooks the above components (reader, writer, proxy) to the store.

var store = new Ext.data.Store({ 

   id: 'user', 
   proxy: proxy, 
   reader: reader, 
   writer: writer, 
   autoSave: false
});

Add the data grid declaration

var grid = new Ext.grid.GridPanel({ 

    store: store, 
    columns: [ 
        { header: "Name", 
            width: 170, 
            sortable: true, 
            dataIndex: 'Name', 
            editor: { 
                xtype: 'textfield', 
                allowBlank: false
            } 
        }, 
        { header: "Phone No.", 
            width: 160, 
            sortable: true, 
            dataIndex: 'Phone', 
            editor: { 
                xtype: 'textfield', 
                allowBlank: false
            } 
        }, 
        { header: "EMail", 
            width: 170, 
            sortable: true, 
            dataIndex: 'Email', 
            editor: { 
                xtype: 'textfield', 
                allowBlank: false
            } 
        } 
    ], 
    plugins: [editor], 
    title: 'Contacts DataGrid', 
    height: 300, 
    width: 510, 
    tbar: [{ 
        iconCls: 'icon-user-add', 
        text: 'Add Contact', 
        handler: function () { 
            var e = new Contact({ 
                Name: 'New Friend', 
                Phone: '(65) 89182736', 
                Email: '[email protected]'
            }); 
            editor.stopEditing(); 
            store.insert(0, e); 
            grid.getView().refresh(); 
            grid.getSelectionModel().selectRow(0); 
            editor.startEditing(0); 
        } 
    }, { 
        ref: '../removeBtn', 
        iconCls: 'icon-user-delete', 
        text: 'Remove Contact', 
        handler: function () { 
            editor.stopEditing(); 
            var s = grid.getSelectionModel().getSelections(); 
            for (var i = 0, r; r = s[i]; i++) { 
                store.remove(r); 
            } 
        } 
    }, { 
        iconCls: 'icon-user-save', 
        text: 'Save All Modifications', 
        handler: function () { 
            store.save(); 
        } 
    }]
});

Some observations:


-
When submitting data as JSON, set the headers “Content-Type” to “application/json” in the proxy object and set the encoding to false in the JsonWriter. If not, it will be treated as form submission.

-
Since I set the auto save to false. DataGrid will submit list of contact when there are 2 or more changes, however it will send a single object when there is 1 change. In order to make it consistent to send as list, set list full to true in the JsonWriter.

-
ASP.NET MVC 3 able to recognize the JSON without additional coding.



European ASP.NET MVC 3 Hosting :: How to Use BCrypt with ASP.NET MVC 3 and C#

clock September 12, 2011 08:58 by author Scott

I was just reading today about yet another site that stored their user’s passwords in plain text. Of course the issue is if you get hacked you expose everyone’s passwords to the world, passwords they might be using on other sites, etc. There is a lot of debate of how you should go about encrypting/hashing/obscuring passwords and with a little research I found a lot of people seem to think BCrypt is the way to go. Check out this article.

I won’t debate on what you should use for your website, you need to make that decision. I played with a
BCrypt C# library I found on Google Code. Today I’ll build a simple ASP.NET MVC 3 app that will use it to show how easy it is to work with in a project.

Open up Visual Studio 2010 and make sure you have the
ASP.NET MVC 3 package installed. Create a new project: File -> New Project -> ASP.NET MVC 3 Web Application and call it MvcBCrypt. For the project template select Empty. Make sure for the View Engine you pick Razor.



Right-click on the Controllers folder and select Add -> Controller

Name the new Controller HomeController.



When the code shows up right-click on the Index() and choose Add View. Use the default settings (see below) and then click Add.



Modify the code in the Index.cshtml file to look like this:

@{
    ViewBag.Title = "Home Page";
}   

<p>Password: @ViewBag.Password</p>
<p>Hashed Password: @ViewBag.HashedPassword</p>
<p>(Use a wrong password) Is the password correct?: @ViewBag.HashedPasswordChecked1</p>
<p>(Use the correct password) Is the password correct?: @ViewBag.HashedPasswordChecked2

Its time to bring in the
BCrypt code now. Go to this link and copy the source code. Create a new folder in your project called Utility and create a new class file in there called BCrypt.cs.



Note: Yes, there are better places to put this new BCrypt class file but for simplicity its just going to live in a Utility folder for this demonstration.

Make sure to paste in the code and save the file. When you do this make sure to fix the namespace and remove the following:

[assembly: System.Reflection.AssemblyVersion("0.3")]

Go back to the HomeController file and modify it like so:

using MvcBCrypt.Utility;

Add the new code to test out the BCrypt class:

public ActionResult Index()
{
    string password = "myPassword1";
    string wrongPassword = "wrongPasswOrd1";   

    string hashedPassword = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
    bool doesItMatch1 = BCrypt.CheckPassword(wrongPassword, hashedPassword);
    bool doesItMatch2 = BCrypt.CheckPassword(password, hashedPassword);   

    ViewBag.Password = password;
    ViewBag.HashedPassword = hashedPassword;
    ViewBag.HashedPasswordChecked1 = doesItMatch1;
    ViewBag.HashedPasswordChecked2 = doesItMatch2;   

    return View();
}

Save and run the project.



Note: Using the new Library Package Manager I did see another BCrypt library out there so you might want to experiment with that one as well.



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]



About HostForLIFE.eu

HostForLIFE.eu 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 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in