Asp.net mvc internals & extensibility

81
MVC Internals & Extensibility Eyal Vardi CEO E4D Solutions LTD Microsoft MVP Visual C# blog: www.eVardi.com

description

Asp.net mvc internals & extensibility

Transcript of Asp.net mvc internals & extensibility

Page 1: Asp.net mvc internals & extensibility

MVC Internals & Extensibility

Eyal Vardi

CEO E4D Solutions LTD

Microsoft MVP Visual C#

blog: www.eVardi.com

Page 2: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Agenda

Routing

Dependency Resolver

Controller Extensibility

Model Extensibility

View Extensibility

Page 3: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

MVC in ASP.NET

Page 4: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

ASP.NET vs. ASP.NET MVC

Page 5: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

MVC Execution Process

ASP.NET

IIS Routing ASP.NET

MVC 3.0

Page 6: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

URL Routing

http://Domain/Path

http://Domain/.../..

URL to Controller

URL to Page

Page 7: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Routes

A route is a URL pattern that is mapped to a handler. The handler can be a physical file, such as an .aspx file in a

Web Forms application.

A handler can also be a class that processes the request, such as a controller in an MVC application.

protected void Application_Start() { RouteTable .Routes .MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL template new { controller="Calc", action="Add", id=UrlParameter.Optional } ); }

Global.asax

Page 8: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

URL Patterns in MVC Applications

{Controller} / {Action} / {id}

Query / {queryname} / {*queryvalues} “*” This is referred to as a catch-all parameter.

/query/select/bikes/onsale queryname = "select" , queryvalues = "bikes/onsale"

Page 9: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

URL Routing Pipeline

Page 10: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Adding Constraints to Routes

Constraints are defined by using regular expressions string or by using objects that implement the IRouteConstraint interface.

protected void Application_Start() { RouteTable .Routes .MapRoute( "Blog", "Posts/{postDate}", new { controller="Blog",action="GetPosts" } ); }

/Posts/28-12-71 => BlogController,GetPosts( “28-12-1971” ) /Post/28 => BlogController,GetPosts( “28” ) /Post/test => BlogController,GetPosts( “test” )

Global.asax

Page 11: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

IRouteConstraint

protected void Application_Start() { RouteTable .Routes .MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL template new { controller="Calc", action="Add", id=UrlParameter.Optional }, new { action = new MyRouteConstraint() } ); }

Custom Route Constraint

Global.asax

Page 12: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Regular Expression Route Constraint

protected void Application_Start() { RouteTable .Routes .MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL template new { controller="Calc", action="Add", id=UrlParameter.Optional }, new { action = @"\d{2}-\d{2}-\d{4}" } ); }

Regular Expression

Page 13: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Route lifecycle

Page 14: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Route

IDependencyResolver

MvcRouteHandler MvcHandler Controller

Routing Process

Page 15: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Route Constraint

Page 16: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Routing Summary

URL Templates Default values

Namespaces

Constraint

IRouteHandler

RouteBase

Page 17: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Dependency Resolver

Service locator for the framework.

protected void Application_Start() { ... DependencyResolver.SetResolver(new TraceDependencyResolver() ); }

Page 18: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Trace Dependency Resolver

Page 19: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Dependency Resolver

Page 20: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Controller Extensibility

Page 21: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Understanding Controllers

MVC controllers are responsible for responding to requests made against an ASP.NET MVC website.

Page 22: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Controller Class

Page 23: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Creation of the Controller

IControllerFactory Responsible for determining the controller to service the request.

IControllerActivator Responsible for creating the controller

DefaultControllerFactory has internal class called DefaultControllerActivator.

Page 24: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Creation of the Controller

Routing

Controller

Factory

Controller

Activator Controller

Dependency

Resolver

MvcRouteHandler MvcHandler Request

Dependency

Resolver

Page 25: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

How Controller Created?

Page 26: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Controller Summary

MvcHandler

IControllerFactory

IControllerActivator

Page 27: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

The Action Execution

Routing

Controller

Factory

Controller

Activator Controller

Action

Invoker

Action

Method

Dependency

Resolver

MvcRouteHandler MvcHandler Request

Dependency

Resolver

Page 28: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

The Action Execution

Once the controller has been instantiated, the specified action has to be executed, and this is handled by the IActionInvoker.

If you derived your controller from the Controller class, then this is the responsibility of an action invoker.

Page 29: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

The Action Execution

Page 30: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Built-In Action Invoker

Finds a method that has the same name as the requested action.

Page 31: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Action Name

You can then accept an action name that wouldn’t be legal as a C# method name. [ActionName("User-Registration")]

[ActionNameSelector]

Page 32: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Action Method Selection

The action invoker uses an action method selector to remove ambiguity when selecting an action.

The invoker gives preference to the actions that have selectors.

Page 33: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Action Method Selector

You return true from IsValidForRequest if the method is able to process a request, and false otherwise.

Page 34: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Method Selector

Page 35: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Handling Unknown Actions

Page 36: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Action Summary

IActionInvoker

Action Name Selector

Action Method Selector

Handling Unknown Actions

Page 37: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Model Extensibility

Page 38: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Model Binding

What Is a Model?

Model

Controller View HTTP HTML

Deserialization

Template

Page 39: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

HTTP to .NET Classes

public ActionResult Index(Reservation reservation) { // TODO BL. return View( reservation ); }

Deserialization

Page 40: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

HTTP to .NET Args

Page 41: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Model Binders

Binders are like type converters, because they can convert HTTP requests into objects that are passed to an action method.

Page 42: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

DefaultModelBinder Class

Translate HTTP request into complex models, including nested types and arrays. URL

Form data, Culture - Sensitive

1. Request.Form

2. RoutedData.Values

3. Request.QueryString

4. Request.Files

(Key,Value)

Page 43: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Model Binder Types

ByteArrayModelBinder

LinqBinaryModelBinder

FormCollectionModelBinder

HttpPostedFileBaseModelBinder

DefaultModelBinder

Page 44: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Binding to Complex Types [DisplayName("Book")] public class E4DBook { [Display(Name = "Title")] public string E4DTitle { get; set; } public Reservation MyReservation { get; set; } }

Model

<label for="MyReservation_FlightNum">FlightNum</label> <input type="text" value="" id = "MyReservation_FlightNum" name = "MyReservation.FlightNum" />

Html

@Html.LabelFor(model => model.MyReservation.FlightNum) @Html.EditorFor(model => model.MyReservation.FlightNum)

View

Page 45: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Specifying Custom Prefixes

<!– First Arg --> <label for="FlightNum">FlightNum</label> <input type="text" id="FlightNum" name="FlightNum" /> ... <!– Second Arg --> <label for="MyRes_FlightNum">FlightNum</label> <input type="text" id="MyRes_FlightNum" name="MyRes.FlightNum" />

Html

public ActionResult Index( Reservation res1 , [Bind(Prefix="myRes")] Reservation res2 ) { ... }

Controller

Page 46: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Bind Attribute (“View”)

Represents an attribute that is used to provide details about how model binding to a parameter should occur.

[Bind(Include = "FlightNum, TravelDate)] public class Reservation { public int FlightNum { get; set; } public DateTime TravelDate { get; set; } public int TicketCount { get; set; } public int DiscountPercent { get; set; } }

Page 47: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Bind Attribute

Page 48: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

<input type="text" name="reservation" /> <input type="text" name="reservation" /> <input type="text" name="reservation" /> <input type="text" name="reservation" />

Html

public ActionResult Index( List< string > reservation ) { ... }

Controller

Binding to a String Collections

Page 49: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Binding to a Collections

<!– Option I--> <input type="text" name="[0].Name" /> <input type="text" name="[1].Name" /> <!– Option II --> <input type="hidden" name="Index" value="f1" /> <input type="text" name="[f1].Name" /> <input type="hidden" name="Index" value="f2" /> <input type="text" name="[f2].Name" />

Html

public ActionResult Index( List<Reservation> reservation ) { ... }

Controller

Page 50: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Binding to a Dictionary

<input type="hidden" name="[0].key" value="f1" /> <input type="text" name="[0].value.Name" /> <input type="hidden" name="[1].key" value="f2" /> <input type="text" name="[1].value.Name" />

Html

public ActionResult Index( Dictionary<Reservation> reservation ) { ... }

Controller

Page 51: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Model Binders

ASP.NET MVC allows us to override both the default model binder, as well as add custom model binders.

ModelBinders.Binders.DefaultBinder = new CustomDefaultBinder(); ModelBinders.Binders.Add( typeof(DateTime), new DateTimeModelBinder() );

Page 52: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

ModelBinder Attribute

Represents an attribute that is used to associate a model type to a model-builder type.

public ActionResult Contact( [ModelBinder(typeof(ContactBinder))] Contact contact ) { ViewData["name"] = contact.Name; ViewData["email"] = contact.Email; ViewData["message"] = contact.Message; ViewData["title"] = "Succes!"; return View(); }

Page 53: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Binder

Page 54: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Page 55: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Model Summary

Http to .NET Classes

IModelBinder

IValueProvider

ModelMetadataProvider

BindAttribute

Validation

Data Annotations

IValidateObject

Page 56: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Action Results

A controller action returns something called an action result.

Action results types:

ViewResult

EmptyResult

RedirectResult

JsonResult

JavaScriptResult

ContentResult

FileContentResult

FilePathResult

FileStreamResult

HttpNotFoundResult

HttpRedirectResult

HttpStatusCodeResult

Page 57: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Action Result

Page 58: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

ASP.NET MVC Filters

Filters are custom classes that provide both a declarative and programmatic means to add pre-action and post-action behavior to controller action methods.

[HandleError] [Authorize] public class CourseController : Controller { [OutputCache] [RequireHttps] public ActionResult Net( string name ) { ViewBag.Course = BL.GetCourse(name); return View(); } }

Page 59: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Action Method Action Result

Filter Interfaces

Page 60: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Filter Order

Filters run in the following order:

Authorization filters

Action filters

Response filters

Exception filters

Page 61: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Controller & Filters

The Controller class implements each of the filter interfaces.

You can implement any of the filters for a specific controller by overriding the controller's On<Filter> method. OnAuthorization

OnActionExecuting

OnActionExecuted

OnResultExecuting

OnResultExecuted

OnException

Page 62: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

IAuthorizationFilter

Make security decisions about whether to execute an action method.

AuthorizeAttribute

RequireHttpsAttribute

Page 63: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

IActionFilter Interface

OnActionExecuting Runs before the action method.

OnActionExecuted Runs after the action method

Page 64: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

IResultFilter Interface

OnResultExecuting Runs before the ActionResult object is executed.

OnResultExecuted Runs after the result.

Can perform additional processing of the result.

The OutputCacheAttribute is one example of a result filter.

Page 65: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

IExceptionFilter

Execute if there is an unhandled exception thrown during the execution of the ASP.NET MVC pipeline.

Can be used for logging or displaying an error page.

HandleErrorAttribute is one example of an exception filter.

Page 66: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Handle Error Attribute

You can specify an exception and the names of a view and layout.

Works only when custom errors are enabled in the Web.config file <customErrors mode="On" /> inside

the <system.web>

The view get HandleErrorInfo

Page 67: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Action Method Action Result

First Global Controller Action Last

Filter I

Filter II

Filter I

Filter II

Filter I

Filter II

Filter I

Filter II

Filter I

Filter II

Action

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Result

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Filter I

Exception

Filter II Filter II

Filter II Filter II

Filter II

Filter I Filter I

Filter I Filter I

Filter I

Authorization

Filter I Filter I

Filter I Filter I

Filter I

Filter II Filter II

Filter II Filter II

Filter II

Page 68: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Action

Before After

Filter I

Filter I

Filter I

Filter I

Filter I

Filter II

Filter II

Filter II

Filter II

Filter II

Filter II

Filter II

Filter II

Filter II

Filter II

Filter I

Filter I

Filter I

Filter I

Filter I

Page 69: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Controller Context

1

2 3 4 5

6

Page 70: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Filters

Page 71: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Filter

You can create a filter in the following ways:

Override one or more of the controller's On<Filter> methods.

Create an attribute class that derives from ActionFilterAttribute or FilterAttribute.

Register a filter with the filter provider (the FilterProviders class).

Register a global filter using the GlobalFilterCollection class.

Page 72: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Custom Filter

Page 73: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

The Filter Provider Interface

Page 74: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Filter Providers

By default, ASP.NET MVC registers the following filter providers:

Filters for global filters.

FilterAttributeFilterProvider for filter attributes.

ControllerInstanceFilterProvider for controller instances.

The GetFilters method returns all of the

IFilterProvider instances in the service locator.

Page 75: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Filter Summary

Custom Filters IAuthorizationFilter

IActionFilter

IResultFilter

IExceptionFilter

IFilterProvider

Page 76: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

View Extensibility

Page 77: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Creating a Custom View Engine

Page 78: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Page 79: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

Page 80: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

View Summary

IViewEngine How to find the view?

IView Render

Page 81: Asp.net mvc internals & extensibility

© 2010 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]

MVC Internals & Extensibility Summary

Routing

Controller

Factory

Controller

Activator Controller

Action

Method

Dependency

Resolver

Mvc

RouteHandler MvcHandler

Dependency

Resolver

Authorization

Filter

Action

Filer

Result

Filter

Exception

Filter View

Action

Invoker Method

Selectror

Name

Selector

Model

Bind

Action

Filer

Result

Filter

View

Engine