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 :: ASP.NET MVC 3 Model Metadata Providers

clock October 5, 2011 09:37 by author Scott

There are different types of filters in MVC. Depending on the type of the Filter, and the scope of the Filter, the order of the execution also changes.

You may already aware that there are different types of filters within MVC framework. They are listed below.

1. Authorization filters
2. Action filters
3. Response/Result filters
4. Exception filters

The above list is ordered as exactly the order they executes within MVC framework. The Authorization filters always run first, and the Exception filters run at the end.

Specifying the Order property for Filters

Within each filter, you may specify the Order property. (All filters are derived from the abstract class FilterAttribute, and this class has an Order property). This property will ensure the filter runs in a specific Order. For an example, let’s say we have 2 Authorization filters, AuthorizationFilterA and AuthorizationFilterB and they are implemented as below.


public class AuthorizationFilterA : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterA");
    }
}

public class AuthorizationFilterB : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterB");
    }
}

Now, if I want these two filters to run in a specific order - AuthorizationFilterB to run first, and AuthorizationFilterA to run second, I can simply specify the execution order as below.


[AuthorizationFilterA(Order=2)]
[AuthorizationFilterB(Order=1)]
public ActionResult Index()
{
    return View();
}

When you run the code, the Output window should display that AuthorizationFilterB runs first, AuthorizationFilterA runs second.

OnAuthorization : AuthorizationFilterB

OnAuthorization : AuthorizationFilterA

Filter Scope

Within each filter type, you can define a scope. For an example, I could scope all my Authorization Filters to run within the Controller Scope, and all Action Filters to run in Global scope (Every Action within the MVC application).

FilterScope.Global is a new scope which was introduced in MVC 3. The existing scopes are First, Controller, Action, and Last. The complete enumeration is defined as below.

namespace System.Web.Mvc {
    public enum FilterScope
        First = 0,
        Global = 10,
        Controller = 20,
        Action = 30,
        Last = 100,
    }
}

By default, the filters with the lowest scope runs first. For an example, scope Global (10) executes first and scope Controller (20) executes second.


Filter Scope with explicit Ordering

Below example shows, how explicit filter ordering (using Order property) and scope of the filters determine their correct run order.

Let’s add the scope to our existing Authorization Filters – AuthorisationFilterA and AuthorisationFilterB. Please note that we haven’t changed the usage of Order property.

AuthorizationFilterA(Order 2) has the scope Global.

AuthorizationFilterB(Order 1) has the scope Action.

public class AuthorizationFilterA : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global");
    }
}

public class AuthorizationFilterB : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action");
    }
}


[AuthorizationFilterB(Order = 1)]
public ActionResult Index()
{
    return View();
}

GobalFilters.Filters.Add(new AuthorizationFilterA() { Order = 2});

According to the above Filter Scope enumeration, if we were to specify only the scope but not the Order property, then we would expect AuthorizationFilterA (in Global scope) to run first, and AuthorizationFilterB (in Action scope) to run second. Since we are explicitly specifying the Order property for both filters, AuthorizationFilterB (in Action scope – Order 1) runs first and AuthorizationFilterA (in Global scope – Order 2) runs second.


Output:

OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action

OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global

Now let’s add another Authorization filter (AuthorizationFilterC) to Global scope. Also note that we have not specified the Order property.

public class AuthorizationFilterC : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            Debug.WriteLine("OnAuthorization : AuthorizationFilterC (no Order defined) in scope : Global");
        }
    }

GlobalFilters.Filters.Add(new AuthorizationFilterC());

After running all three filters, you can see the output as below. 

Output

OnAuthorization : AuthorizationFilterC (no Order defined) in scope : Global

OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action

OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global

For same Filter type, the filters without the explicit ordering (i.e AuthorizationFilterC) take precedence over the filters with explicit ordering (AuthorizationFilterB, AuthorizationFilterA).

Now let’s remove the Order property from both AuthorizationFilterB and AuthorizationFilterA

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

GlobalFilters.Filters.Add(new AuthorizationFilterA());

Output:

OnAuthorization : AuthorizationFilterA (no order defined) in scope : Global

OnAuthorization : AuthorizationFilterC (no order defined) in scope : Global

OnAuthorization : AuthorizationFilterB (no order defined) in scope : Action

As we would expect, the filters with scope Global (AuthorizationFilterA and AuthorizationFilterC) run first and second in order, the scope Action filter (AuthorizationFilterC) runs at the end. 2 Global filters (AuthorizationFilterA and AuthorizationFilterC) run order relies on the order which they were added to the Global Filter collection. In this example AuthorizationFilterA which was added prior to AuthorizationFilterC , runs first.

For the same filters, when determine the run order, first it sorts them by their order (lowest numbers first), and then by their scope (also lowest numbers first).

Controller as a Filter

In MVC the Controller itself is also a Filter. Controller implements all filters, so Controller can subscribe to all filter events.

public abstract class Controller : ControllerBase,
IActionFilter, IAuthorizationFilter, IDisposable,
IExceptionFilter, IResultFilter

MVC framework ensures, the Controller always runs first, before any other filters get executed. It has been accomplished by specifying the scope as the First and the order property as Int32.MinValue. By default, an MVC filter has the value for the Order -1. Therefore Int32.MinValue along with the Scope First together ensures the Controller always runs first.

public class ControllerInstanceFilterProvider : IFilterProvider {
        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
            if (controllerContext.Controller != null) {
               
// Use FilterScope.First and Order of Int32.MinValue to ensure controller instance methods always run first
                yield return new Filter(controllerContext.Controller, FilterScope.First, Int32.MinValue);
            }
        }
    }

Forward Filter Order and Reverse Filter Order

So far we have discussed the order of filters which get executed based on the explicit ordering (using Order property) and the scope which they can be belong to. However, MVC filters run order, do not only rely only by these two factors. Sometimes filters run in forward order and sometimes filters run in reverse order. Let’s see the below example.

Let’s say I have three Action filters (ActionFilter1, ActionFilter2, ActionFilter3), one Authorization filter (AuthorizationFilter) and two Exception filters (HandleErrorA, HandleErrorB). They are implemented as below.

public class ActionFilter1 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter1 (Scope Global)");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter1 (Scope Global)");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter1 (Scope Global)");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter1 (Scope Global)");
    }
}


public class ActionFilter2 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter2 (Scope Controller)");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter2 (Scope Controller)");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter2 (Scope Controller)");
    } 

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter2 (Scope Controller)");
    }
}

public class ActionFilter3 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter3 (Scope Action)");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter3 (Scope Action)");
    } 

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter3 (Scope Action)");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter3 (Scope Action)");
    }
}    


public class AuthorizationFilter : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnAuthorization : AuthorizationFilter (Scope Controller)");
    }
}   


public class HandleErrorA : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnException : HandleErrorA (Scope Action)");
    }
}

public class HandleErrorB : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnException : HandleErrorB (Scope Action)");
    }
}

We will register the above filters as below…


ActionFilter1 has the scope Global, ActionFIlter2 has the scope Controller, ActionFIlter3 has the Scope Action, AuthorizationFilter has the scope Controller, HandleErrorA has the scope Global, and HandleErrorB has the scope Action.

At the beginning of this article I mentioned that the run order of different types of filters. First Authorization filters, then Action Filters, followed by Result filters and at the end the Exception filters. This is true, however within each type of filters, some executes in reverse order and some executes in forward order.

The best way to explain is to examine the generated output.

Forward Order - OnAuthorization : AuthorizationFilter (Scope Controller)

Forward Order - OnActionExecuting : ActionFilter1 (Scope Global)

Forward Order - OnActionExecuting : ActionFilter2 (Scope Controller)

Forward Order - OnActionExecuting : ActionFilter3 (Scope Action)

Home Controller, Index Action

Reverse Order - OnActionExecuted : ActionFilter3 (Scope Action)

Reverse Order - OnActionExecuted : ActionFilter2 (Scope Controller)

Reverse Order - OnActionExecuted : ActionFilter1 (Scope Global)

Forward Order - OnResultExecuting : ActionFilter1 (Scope Global)

Forward Order - OnResultExecuting : ActionFilter2 (Scope Controller)

Forward Order - OnResultExecuting : ActionFilter3 (Scope Action)

Reverse Order - OnResultExecuted : ActionFilter3 (Scope Action)

Reverse Order - OnResultExecuted : ActionFilter2 (Scope Controller)

Reverse Order - OnResultExecuted : ActionFilter1 (Scope Global)

Reverse Order - OnException : HandleErrorB (Scope Action)

Reverse Order - OnException : HandleErrorA (Scope Global)

-
There is only one Authorization Filter in Controller scope and it runs first as expected.

-
The Action Filters run at second. Notice that OnActionExecuting event runs in an order where the order of filter execution is determined by their scope (lowest number first in the enumeration). As you see, Action Filters OnActionExecuting event runs in a forward order.

-
Home Controller’s Index Action executes.

-
Action Filters do not always run in forward order. As you see during OnActionExecuted event, they run in a reverse order.

-
Very similar to OnActionExecuted event, OnResultExecuted event runs in reverse order.

-
Error Handler filters run at last. For each Error Handler filter, OnException event runs in  reverse order. Prior to MVC 3, ErrorHandler’s OnException event ran in forward order. This approach makes MVC exception filters more aligned with .NET exception handlers.

Summary

There are multiple factors involved when deciding the run order of MVC filters. This includes the explicit ordering, the scope they belong to, and the type of the filter. Controller itself is a filter and always run first. By design, MVC executes certain filters in specific order. Some are run in forward order and some are run in reverse order.

 



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



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