ASP.NET MVC
Why MVC
Advantages:
Separation of Concerns
Easily Extensible
Testable [TDD is possible]
Lightweight [No ViewData]
Full Control on View Rendering [HTML]
Disadvantages:
More Learning Curve
More Complex
Rapid Prototype is not supported [Drag n Drop]
How MVC Works
Models
Model Binder
DataAnnotations
View Model vs Entities (Business Layer) vs Data Model (Data Layer)
Models - Model Binder
Form Model Binder
Default Model Binder
Custom Model Binder
Value Provider
Binding Collection/List and Dictionary
Models - Model Binder - FormCollection
It is collection of key/value pair
Needs to map each value with property of model manually
Needs manual casting as well
Models - Model Binder - DefaultModelBinder
It is default model binder.
It plays an important role in conversion and mapping of model properties
Models - Model Binder - Custom ModelBinder
For complex scenario, application demands to build custom model binder to satisfy specific
requirement.
It is very helpful when UI developer doesn’t know about model.
Models - Model Binder - Attribute
Models - Model Binder - Value Providers
Model Binding is two step process:
1. Collecting values from requests using Value Providers
2. Populating models with those values using Model Binders
Below are the available value providers. Number indicates priority, and based on priority, Model
Binders looks into Value Providers to find specific value of a model property.
1. Form Fields [Request.Form]
2. JSON Request Body [Request.InputStream - only when request is an Ajax]
3. Routedata [RouteData.Values]
4. Query String Values [Request.QueryString]
5. Posted Files [Request.Files]
Models - Model Binder - List/Collection
Models - Model Binder - Dictionary
HomeWork
Custom Value Provider - Cookie - http://snag.gy/Q31Le.jpg
Models - DataAnnotations
Validation DataAnnotations
Other DataAnnotations
Custom Validation Attribute
ModelState
Models - DataAnnotations - Validation
[Required]
[Required(ErrorMessage="")]
[Required(ErrorMessageResourceName="{Key}" ErrorMessageResourceType=typeof(T))]
[StringLength(12, MinimumLength = 6, ErrorMessage = "")]
[Compare("Password", ErrorMessage = "")]
[ValidatePasswordLength]
[Range(18, 65, ErrorMessage = "")]
[RegularExpression(@"d{1,3}", ErrorMessage = "")]
[Remote("{Action}", "{ControllerName}", ErrorMessage = "")]
public ActionResult ValidateUserName(string username)
{
return Json(!username.Equals("duplicate"), JsonRequestBehavior.AllowGet);
}
[Remote("{Route}", HttpMethod="Post", AdditionalFields="Email", ErrorMessage = "")]
[HttpPost]
public ActionResult ValidateUserName(string username, string email /*AdditionalFields*/)
{
// put some validation
return Json(true);
}
Models - DataAnnotations - Other
//Lists fields to exclude or include when binding parameter or form values to model properties
[Bind(Exclude=”{PropertyName}”)]
//Hides the input control
[HiddenInput(DisplayValue=false)]
//To display customized date format
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy hh:mm}")]
//If value is NULL, "Null Message" text will be displayed.
[DisplayFormat(NullDisplayText = "Null Message")]
//If you don’t want to display a column use ScaffoldColumn attribute.
//This only works when you use @Html.DisplayForModel() helper
It is used to control whether values are shown on display templates and edit fields are shown on editor templates
[ScaffoldColumn(false)]
/*Specifies the template or user control that Dynamic Data uses to display a data field
If you annotate a property with UIHint attribute and use EditorFor or DisplayFor inside your views,
ASP.NET MVC framework will look for the specified template which you specified through UIHintAttribute.
The directories it looks for is:
For EditorFor: ~/Views/Shared/EditorTemplates, ~/Views/Controller_Name/EditorTemplates
For DisplayFor: ~/Views/Shared/DisplayTemplates, ~/Views/Controller_Name/DisplayTemplates
*/
[UIHint("StarRating")]
public int Rating { get; set; }
/*StarRating.cshtml*/
@model int
<img src="@Url.Content("~/Content/Images/star-" + Model.ToString("00") + ".png")" title="Rated @Model.ToString()/10" />
Models - DataAnnotations - Custom Annotations
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class NotEqualToAttribute : ValidationAttribute
{
private const string DefaultErrorMessage = "{0} cannot be the same as {1}.";
public string OtherProperty { get; private set; }
public NotEqualToAttribute(string otherProperty): base(DefaultErrorMessage)
{
if (string.IsNullOrEmpty(otherProperty))
{
throw new ArgumentNullException("otherProperty");
}
OtherProperty = otherProperty;
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name, OtherProperty);
}
protected override ValidationResult IsValid(object value,ValidationContext validationContext)
{
if (value != null)
{
var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(OtherProperty);
var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
if (value.Equals(otherPropertyValue))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return ValidationResult.Success;
}
}
Models - DataAnnotations - Model State
[AllowAnonymous]
[HttpPost]
public JsonResult SignUp(RegisterModel model)
{
if (ModelState.IsValid)//Checks all data annotations based on their values
{
//TODO:
}
return Json(new
{
success = false,
errors = ModelState.Keys.SelectMany(k => ModelState[k].Errors)
.Select(m => m.ErrorMessage).ToArray()
});
}
Models - DataAnnotations - Model State - Extension
Model State can be easily extended with IValidatableObject interface. Custom validation logic can be written while implementing
interface method “Validate”.
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Mobile != null && !Mobile.StartsWith("91"))
{
yield return new ValidationResult("India country code is required", new[] { "Mobile" });
}
}
The order of operations for the IValidatableObject to get called:
1. Property attributes
2. Class attributes
3. Validate interface
If any of the steps fail it will return immediately and not continue processing.
Model State can be modified before sending final result to view.
ModelState.Remove("Id"); // Removes validation error for this property if exists
ModelState.AddModelError("<Property>", "<Message>");
try
{
...
}
catch
{
ModelState.AddModelError("", "Throttling limit is reached.");
return;
}
Models - DataAnnotations - Model State - Advance
Views
Views - Layouts, Views, Partial Views
Passing Data into Views
Razor - HTML Helpers - Default, Custom; Sections; ViewEngine Customization
Views - Conventional Structure
Views - Layout with ViewStart
Layout is master page
Layout can be configured for each view - using ViewStart.cshtml
Layout can be configured for view folder - creating ViewStart.cshtml in that folder
Layout can be configured in each view individually with setting Layout property
Nested Layout can be configured - Parent/Child or Header/Footer/LeftBar/RightBar
Views - View and Partial View
View is Razor template - HTML snippet. A view can’t have views
Partial View is also Razor template - HTML snippet - Reusable. A view can have partial views.
Rendering Partial Views:
1. Html.Partial - Returns string, can be manipulated later
2. Html.Action - Returns string, can be manipulated later, cacheable
3. Html.RenderPartial - Returns void, content will be written with parent view into stream directly,
gives better performance.
4. Html.RenderAction - Returns void, content will be written with parent view into stream directly,
gives better performance, cacheable.
Views - Passing Data into View
ViewData - Dictionary, needs casting, life: Action to View
ViewBag - dynamic, doesn’t need casting, ViewData wrapper, life: Action to View
Session - dictionary, needs casting, life: across application
TempData - dictionary, needs casting, Session wrapper, life: Action to any action
Model - Passing model in view argument - Strongly Typed View
Razor
Razor - @
Razor code is C#, so all conventions and features are inherited
Razor - @
@{model.property = 20;}
@model.property => 20
@model.property / 10 => 20 / 10
@(model.property / 10) => 2
text@model.property => text@20
text@(model.property) => text2
@my_twitter_handle => error
@@my_twitter_handle => @my_twitter_handle
Razor - Html Helpers
Html.BeginForm
Html.EndForm
Html.TextBox/Html.TextBoxFor
Html.TextArea/Html.TextAreaFor
Html.Password/Html.PasswordFor
Html.Hidden/Html.HiddenFor
Html.CheckBox/Html.CheckBoxFor
Html.RadioButton/Html.RadioButtonFor
Html.DropDownList/Html.DropDownListFor
Html.ListBox/Html.ListBoxFor
Razor - Custom Html Helper
A method that returns IHtmlString (4.0) or MvcHtmlString (before 4.0)
1. Static Method that returns above return type
2. Extension method
3. @helper
Razor - Custom Html Helper
A method that returns IHtmlString (4.0) or MvcHtmlString (before 4.0)
1. Static Method that returns above return type
2. Extension method
3. @helper
Razor - Sections
Views - Default Locations
Views - View Engine Customization
There are two ways:
1. Override existing view engines - Razor or WebForms
2. Create new engine with IViewEngine and IView
public interface IViewEngine
{
ViewEngineResult FindPartialView(ControllerContext controllerContext,
string partialViewName, bool useCache);
ViewEngineResult FindView(ControllerContext controllerContext,
string viewName,string masterName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view);
}
public interface IView
{
void Render(ViewContext viewContext, TextWriter writer);
}
Security
There are two kind of securities that will be taken care while building views:
1. XSS
2. CSRF
Security - XSS
Injecting script that steals sensitive informations like cookies etc.
1. Someone hacked view rendering data - always render encoded html or use AntiXSS
1. System allows to enter scripts/html data - always render encoded html or use AntiXSS
Attributes that allows html content posting:
1. ValidateInput - allows html for any property
2. AllowHtml - allows html for specific property
Security - CSRF
Security - CSRF
Routing
Global Routing
Route Constraints
Route Handlers
Routing - Global
Routing - Global
Routing - Custom Route Constraint
Routing - Custom Route Handler
Routing - When is is not applicable
> Existence of Physical File that Matches The URL/Route Pattern
How to handle those requests: routes.RouteExistingFiles = true;
> Restriction of Content like images, css and styles.
[ContentAuthorize]
public FileResult Index()
{
return File(Request.RawUrl, "image/jpeg");
}
> Securing Specific Folders
routes.IgnoreRoute("Content/{*relpath}");
> How to prevent routing from handling requests for the WebResource.axd file
routes.Ignore("{resource}.axd/{*pathInfo}");
Routing - Attribute Routing
New Feature in MVC 5
Homework
Controllers
AllowAnonymous
NoAction
Custom Action Result
Filters
Attributes
Filter Types
Extending Filters
Filters - What
How to modify default processing execution of Request/Response lifecycle?
Example:
public ActionResult Index()
{
if(!IsAuthorized())
{
//Stop processing and return error
}
return View();
}
MSDN says:
“
Sometimes you want to perform logic either before an action method is called or after an action method runs.
To support this, ASP.NET MVC provides 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. “
Filters are just Attributes.
Filters - Attributes
Attributes are meta data that contains custom logic that will be executed at given points.
Custom Attributes
public class HelpAttribute : Attribute
{
public HelpAttribute()
{
}
public String Description{get;set;}
}
[Help(Description = "This is user class contains all information about users and their business flow")]
public class User
{
[Help(Description = "This value is used in Authenticate() method.")]
public string UserName {get;set;}
[Help(Description = "This value is used in Authenticate() method.")]
public string Password {get;set;}
[Help(Description = "This method requires UserName and Password field. So please set those fields before calling this
method.")]
public bool Authenticate()
{
return true;
}
}
Filters - Attributes
public class HelpDocument<T>
{
private void Print(Attribute attr)
{
var ha = attr as HelpAttribute;
if (ha != null)
{
Console.WriteLine(ha.Description);
}
}
public void Build(T bo)
{
//Querying Class Attributes
foreach (Attribute attr in type.GetCustomAttributes(true))
{
Print(attr);
}
//Querying Class-Method Attributes
foreach(MethodInfo method in type.GetMethods())
{
Print(attr);
}
//Querying Class-Field (only public) Attributes
foreach(FieldInfo field in type.GetFields())
{
Print(attr);
}
}
}
Filters - Attributes
public class HelpDocument<T>
{
private void Print(Attribute attr)
{
var ha = attr as HelpAttribute;
if (ha != null)
{
Console.WriteLine(ha.Description);
}
}
public void Build(T bo)
{
//Querying Class Attributes
foreach (Attribute attr in type.GetCustomAttributes(true))
{
Print(attr);
}
//Querying Class-Method Attributes
foreach(MethodInfo method in type.GetMethods())
{
Print(attr);
}
//Querying Class-Field (only public) Attributes
foreach(FieldInfo field in type.GetFields())
{
Print(attr);
}
}
}
Filters - Types
Types of Filters [http://snag.gy/DsYnt.jpg]
1. Authentication (IAuthenticationFilter, AuthenticationAttribute) - Runs first, before any other filters or the action method
2. Authorization (IAuthorizationFilter, AuthorizeAttribute) - Runs first, before any other filters or the action method
3. Action (IActionFilter, ActionFilterAttribute) - Runs before and after the action method
4. Result (IResultFilter, ActionFilterAttribute) - Runs before and after the action result is executed
5. Exception (IExceptionFilter, HandleErrorAttribute) - Runs only if another filter, the action method, or the action result
throws an exception
Filters - Extensibility
There are two ways to extend filters
1. Override existing one
2. Create your own
Filters - Ordering
Filters - Extension - Authentication
public class BasicAuthAttribute : ActionFilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
var user = filterContext.HttpContext.User;
if (user == null || !user.Identity.IsAuthenticated)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
Filters - Extension - Authorization
public class BlackListAuthorizeAttribute : AuthorizeAttribute
{
private string[] disAllowedUsers;
public BlackListAuthorizeAttribute(params string[] disAllowedUsers)
{
this.disAllowedUsers = disAllowedUsers;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool isAuthenticated = httpContext.Request.IsAuthenticated;
bool isInBlackList = disAllowedUsers.Contains(httpContext.User.Identity.Name, StringComparer.InvariantCultureIgnoreCase);
return isAuthenticated && !isInBlackList;
}
}
[BlackListAuthorize("homer", "moe")]
public ActionResult Index()
{
return View();
}
Filters - Extension - Action
public class LoggingFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Trace.Write("(Logging Filter)Action Executing: " +
filterContext.ActionDescriptor.ActionName);
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception != null)
filterContext.HttpContext.Trace.Write("(Logging Filter)Exception thrown");
base.OnActionExecuted(filterContext);
}
}
Filters - Extension - Result
public class SqlCacheAttribute : FilterAttribute, IResultFilter, IActionFilter
{
private string _SqlContent = "";
private string _Key = "";
private string CacheKey(ControllerContext filterContext)
{
string key="";//TODO: Your Logic
return key;
}
private void CacheResult(ResultExecutingContext filterContext)
{
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
_Key = CreateKey(filterContext);
_SqlContent = GetCacheValue(key);
if (!string.IsNullOrWhiteSpace(_SqlContent))
{
filterContext.Result = new ContentResult();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
if (!string.IsNullOrWhiteSpace(_SqlContent))
{
filterContext.HttpContext.Response.Write(_SqlContent);
return;
}
CacheResult(filterContext);
}
public void OnResultExecuting(ResultExecutingContext filterContext)
{
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}
Filters - Extension - Exception
Limitations of HandleError
1. Not support to log the exceptions
2. Doesn't catch HTTP exceptions other than 500
3. Doesn't catch exceptions that are raised outside controllers
4. Returns error view even for exceptions raised in AJAX calls
public class HandleAjaxErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
// return json data
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
}
return;
}
}
Filters - Execution Cancellation
By setting the Result property to a non-null value, further execution will be cancelled.
Example:
OnActionExecuting1,OnActionExecuted1, OnResultExecuting1, OnResultExecuted1
OnActionExecuting2,OnActionExecuted2, OnResultExecuting2, OnResultExecuted2
OnActionExecuting3,OnActionExecuted3, OnResultExecuting3, OnResultExecuted3
OnActionExecuting2, filterContext.Result = new RedirectResult("~/Home/Index"); //non-null value
Cancelled => OnActionExecuted2, OnActionExecuting3, OnActionExecuted3
Filters - Registration
a. Global Filter - http://snag.gy/ZqdDe.jpg
b. Controller Filter - Class
c. Action Filter - Method
Dependency Injection: Introduction
1. Install nuget package - Install-Package Ninject.MVC5
2. Load/Register services
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IHomeService>().To<HomeService>();
}
1. Create controller constructor
public class HomeController : Controller
{
IHomeService _Service;
public HomeController(IHomeService service)
{
_Service = service;
}
Bundling and Minification
Ajax
Get
Post
Ajax - Get
$.ajax({
url: '/Ajax/Index'
, type: 'Get'
, contentType: 'application/json; charset=utf-8'
, dataType: 'json'
, success: function (response) {
console.log(response);
alert(response);
}
, error: function (req, status, error) {
//TODO: error handling
}
});
Ajax - Post
$.ajax({
url: '/Ajax/Index'
, type: 'Post'
, contentType: 'application/json; charset=utf-8'
, dataType: 'json'
, data: '{"a2":"test","a1":5}'
, success: function (response) {
console.log(response);
alert(response);
}
, error: function (req, status, error) {
//TODO: error handling
}
});
Questions
Ajax - Unobtrusive Ajax
@Ajax.ActionLink(category, "GetProductData",
new { selectedCategory = category },
new AjaxOptions { UpdateTargetId = "productsTable",
OnBegin = "OnAjaxRequestBegin",
OnFailure = "OnAjaxRequestFailure",
OnSuccess = "OnAjaxRequestSuccess",
OnComplete = "OnAjaxRequestComplete"})
<script type="text/javascript">
function OnAjaxRequestBegin() {
alert("This is the OnBegin Callback");
}
function OnAjaxRequestSuccess(data) {
alert("This is the OnSuccessCallback: " + data);
}
function OnAjaxRequestFailure(request, error) {
alert("This is the OnFailure Callback:" + error);
}
function OnAjaxRequestComplete(request, status) {
alert("This is the OnComplete Callback: " + status);
}
</script>
Ajax - Unobtrusive Ajax
AjaxOptions ajaxOptions = new AjaxOptions
{
UpdateTargetId = "productsTable",
LoadingElementId = "loadingProducts",
LoadingElementDuration = 1000,
Confirm = "Do you really want to display products?"
};
@using (Ajax.BeginForm("GetProductData", ajaxOptions))
{
}

More Related Content

PPTX
Asp.net mvc training
PDF
Spring 3: What's New
PPTX
Angular JS
PPTX
Getting Started with Angular JS
PDF
當ZK遇見Front-End
PDF
Knockoutjs databinding
PDF
AngularJS Basic Training
PPTX
Angular Js Basics
Asp.net mvc training
Spring 3: What's New
Angular JS
Getting Started with Angular JS
當ZK遇見Front-End
Knockoutjs databinding
AngularJS Basic Training
Angular Js Basics

What's hot (20)

PPTX
Angular workshop - Full Development Guide
PDF
ASPNET_MVC_Tutorial_06_CS
PPT
PPT
Entity Manager
PPTX
Mvc & java script
PPTX
The Magic of WPF & MVVM
PDF
Jsf Framework
PPTX
The AngularJS way
PPT
Code Camp 06 Model View Presenter Architecture
PPTX
Data Binding - Android by Harin Trivedi
PPTX
Angular js 1.0-fundamentals
PPTX
Model View Presenter presentation
PPTX
Introduction to XAML and its features
PDF
Java server faces
PPTX
ASP.NET MVC 3.0 Validation
KEY
AngularJS for designers and developers
PDF
Dialogs in Android MVVM (14.11.2019)
PPTX
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
PPTX
Angular Presentation
PPTX
Academy PRO: ASP .NET Core MVC
Angular workshop - Full Development Guide
ASPNET_MVC_Tutorial_06_CS
Entity Manager
Mvc & java script
The Magic of WPF & MVVM
Jsf Framework
The AngularJS way
Code Camp 06 Model View Presenter Architecture
Data Binding - Android by Harin Trivedi
Angular js 1.0-fundamentals
Model View Presenter presentation
Introduction to XAML and its features
Java server faces
ASP.NET MVC 3.0 Validation
AngularJS for designers and developers
Dialogs in Android MVVM (14.11.2019)
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
Angular Presentation
Academy PRO: ASP .NET Core MVC
Ad

Viewers also liked (15)

PDF
SREEJITH_CV
PDF
Moss-Adams_2012-Corp-Social-Responsibility-Report
PDF
INTERCORP presentation_UPDATE 13_01
PPTX
piscologia
PDF
Mineria cuadros estadisiticos
PDF
Truite t wk10_final_portfolio_v2
PPTX
Recursamiento diseña-y-administra-plataformas-e-learning
PPT
Profile -Harbin Dadi
PPTX
Maven ii
DOC
Shamal Solutions resume
PDF
Uso de la b, v
PPTX
IDS v11.16.04
PPTX
Exploring Altmetrics with Impactstory
PPTX
Maven part 1
PPTX
Simple web service vm
SREEJITH_CV
Moss-Adams_2012-Corp-Social-Responsibility-Report
INTERCORP presentation_UPDATE 13_01
piscologia
Mineria cuadros estadisiticos
Truite t wk10_final_portfolio_v2
Recursamiento diseña-y-administra-plataformas-e-learning
Profile -Harbin Dadi
Maven ii
Shamal Solutions resume
Uso de la b, v
IDS v11.16.04
Exploring Altmetrics with Impactstory
Maven part 1
Simple web service vm
Ad

Similar to Asp.NET MVC (20)

PPTX
Asp.Net MVC 5 in Arabic
PPTX
ASP.MVC Training
PPTX
ASP.NET MVC 5 - EF 6 - VS2015
PPTX
MVC & SQL_In_1_Hour
PPTX
Retrofit Web Forms with MVC & T4
PPTX
MVC and Razor - Doc. v1.2
PDF
Murach: How to transfer data from controllers
PPTX
MVC Training Part 2
DOCX
asp.net - for merge.docx
PDF
ASP.net Manual final.pdf
PDF
ASP.NET MVC 2.0
DOCX
LearningMVCWithLINQToSQL
PPT
MVC ppt presentation
PPTX
MVC Training Part 1
PPTX
Tightly coupled view (model bounded view)
PPTX
Asp.Net MVC Intro
PPTX
ASP.NET MVC.
 
PPTX
MVVM with WPF
 
PPT
ASP .net MVC
PPTX
Asp.Net Mvc
Asp.Net MVC 5 in Arabic
ASP.MVC Training
ASP.NET MVC 5 - EF 6 - VS2015
MVC & SQL_In_1_Hour
Retrofit Web Forms with MVC & T4
MVC and Razor - Doc. v1.2
Murach: How to transfer data from controllers
MVC Training Part 2
asp.net - for merge.docx
ASP.net Manual final.pdf
ASP.NET MVC 2.0
LearningMVCWithLINQToSQL
MVC ppt presentation
MVC Training Part 1
Tightly coupled view (model bounded view)
Asp.Net MVC Intro
ASP.NET MVC.
 
MVVM with WPF
 
ASP .net MVC
Asp.Net Mvc

Recently uploaded (20)

PPTX
WJQSJXNAZJVCVSAXJHBZKSJXKJKXJSBHJBJEHHJB
PDF
How to Set Realistic Project Milestones and Deadlines
PPTX
Human Computer Interaction lecture Chapter 2.pptx
PPTX
Streamlining Project Management in the AV Industry with D-Tools for Zoho CRM ...
PDF
WhatsApp Chatbots The Key to Scalable Customer Support.pdf
PPTX
Chapter_05_System Modeling for software engineering
PPTX
Swiggy API Scraping A Comprehensive Guide on Data Sets and Applications.pptx
PDF
Sanket Mhaiskar Resume - Senior Software Engineer (Backend, AI)
PPTX
Greedy best-first search algorithm always selects the path which appears best...
PPTX
Post-Migration Optimization Playbook: Getting the Most Out of Your New Adobe ...
PPTX
UNIT II: Software design, software .pptx
PDF
Odoo Construction Management System by CandidRoot
PDF
Top AI Tools for Project Managers: My 2025 AI Stack
PDF
Mobile App for Guard Tour and Reporting.pdf
PDF
SOFTWARE ENGINEERING Software Engineering (3rd Edition) by K.K. Aggarwal & Yo...
PDF
Mobile App Backend Development with WordPress REST API: The Complete eBook
PPTX
Beige and Black Minimalist Project Deck Presentation (1).pptx
PDF
solman-7.0-ehp1-sp21-incident-management
PPTX
StacksandQueuesCLASS 12 COMPUTER SCIENCE.pptx
PPTX
ROI from Efficient Content & Campaign Management in the Digital Media Industry
WJQSJXNAZJVCVSAXJHBZKSJXKJKXJSBHJBJEHHJB
How to Set Realistic Project Milestones and Deadlines
Human Computer Interaction lecture Chapter 2.pptx
Streamlining Project Management in the AV Industry with D-Tools for Zoho CRM ...
WhatsApp Chatbots The Key to Scalable Customer Support.pdf
Chapter_05_System Modeling for software engineering
Swiggy API Scraping A Comprehensive Guide on Data Sets and Applications.pptx
Sanket Mhaiskar Resume - Senior Software Engineer (Backend, AI)
Greedy best-first search algorithm always selects the path which appears best...
Post-Migration Optimization Playbook: Getting the Most Out of Your New Adobe ...
UNIT II: Software design, software .pptx
Odoo Construction Management System by CandidRoot
Top AI Tools for Project Managers: My 2025 AI Stack
Mobile App for Guard Tour and Reporting.pdf
SOFTWARE ENGINEERING Software Engineering (3rd Edition) by K.K. Aggarwal & Yo...
Mobile App Backend Development with WordPress REST API: The Complete eBook
Beige and Black Minimalist Project Deck Presentation (1).pptx
solman-7.0-ehp1-sp21-incident-management
StacksandQueuesCLASS 12 COMPUTER SCIENCE.pptx
ROI from Efficient Content & Campaign Management in the Digital Media Industry

Asp.NET MVC

  • 2. Why MVC Advantages: Separation of Concerns Easily Extensible Testable [TDD is possible] Lightweight [No ViewData] Full Control on View Rendering [HTML] Disadvantages: More Learning Curve More Complex Rapid Prototype is not supported [Drag n Drop]
  • 4. Models Model Binder DataAnnotations View Model vs Entities (Business Layer) vs Data Model (Data Layer)
  • 5. Models - Model Binder Form Model Binder Default Model Binder Custom Model Binder Value Provider Binding Collection/List and Dictionary
  • 6. Models - Model Binder - FormCollection It is collection of key/value pair Needs to map each value with property of model manually Needs manual casting as well
  • 7. Models - Model Binder - DefaultModelBinder It is default model binder. It plays an important role in conversion and mapping of model properties
  • 8. Models - Model Binder - Custom ModelBinder For complex scenario, application demands to build custom model binder to satisfy specific requirement. It is very helpful when UI developer doesn’t know about model.
  • 9. Models - Model Binder - Attribute
  • 10. Models - Model Binder - Value Providers Model Binding is two step process: 1. Collecting values from requests using Value Providers 2. Populating models with those values using Model Binders Below are the available value providers. Number indicates priority, and based on priority, Model Binders looks into Value Providers to find specific value of a model property. 1. Form Fields [Request.Form] 2. JSON Request Body [Request.InputStream - only when request is an Ajax] 3. Routedata [RouteData.Values] 4. Query String Values [Request.QueryString] 5. Posted Files [Request.Files]
  • 11. Models - Model Binder - List/Collection
  • 12. Models - Model Binder - Dictionary
  • 13. HomeWork Custom Value Provider - Cookie - http://snag.gy/Q31Le.jpg
  • 14. Models - DataAnnotations Validation DataAnnotations Other DataAnnotations Custom Validation Attribute ModelState
  • 15. Models - DataAnnotations - Validation [Required] [Required(ErrorMessage="")] [Required(ErrorMessageResourceName="{Key}" ErrorMessageResourceType=typeof(T))] [StringLength(12, MinimumLength = 6, ErrorMessage = "")] [Compare("Password", ErrorMessage = "")] [ValidatePasswordLength] [Range(18, 65, ErrorMessage = "")] [RegularExpression(@"d{1,3}", ErrorMessage = "")] [Remote("{Action}", "{ControllerName}", ErrorMessage = "")] public ActionResult ValidateUserName(string username) { return Json(!username.Equals("duplicate"), JsonRequestBehavior.AllowGet); } [Remote("{Route}", HttpMethod="Post", AdditionalFields="Email", ErrorMessage = "")] [HttpPost] public ActionResult ValidateUserName(string username, string email /*AdditionalFields*/) { // put some validation return Json(true); }
  • 16. Models - DataAnnotations - Other //Lists fields to exclude or include when binding parameter or form values to model properties [Bind(Exclude=”{PropertyName}”)] //Hides the input control [HiddenInput(DisplayValue=false)] //To display customized date format [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy hh:mm}")] //If value is NULL, "Null Message" text will be displayed. [DisplayFormat(NullDisplayText = "Null Message")] //If you don’t want to display a column use ScaffoldColumn attribute. //This only works when you use @Html.DisplayForModel() helper It is used to control whether values are shown on display templates and edit fields are shown on editor templates [ScaffoldColumn(false)] /*Specifies the template or user control that Dynamic Data uses to display a data field If you annotate a property with UIHint attribute and use EditorFor or DisplayFor inside your views, ASP.NET MVC framework will look for the specified template which you specified through UIHintAttribute. The directories it looks for is: For EditorFor: ~/Views/Shared/EditorTemplates, ~/Views/Controller_Name/EditorTemplates For DisplayFor: ~/Views/Shared/DisplayTemplates, ~/Views/Controller_Name/DisplayTemplates */ [UIHint("StarRating")] public int Rating { get; set; } /*StarRating.cshtml*/ @model int <img src="@Url.Content("~/Content/Images/star-" + Model.ToString("00") + ".png")" title="Rated @Model.ToString()/10" />
  • 17. Models - DataAnnotations - Custom Annotations [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public sealed class NotEqualToAttribute : ValidationAttribute { private const string DefaultErrorMessage = "{0} cannot be the same as {1}."; public string OtherProperty { get; private set; } public NotEqualToAttribute(string otherProperty): base(DefaultErrorMessage) { if (string.IsNullOrEmpty(otherProperty)) { throw new ArgumentNullException("otherProperty"); } OtherProperty = otherProperty; } public override string FormatErrorMessage(string name) { return string.Format(ErrorMessageString, name, OtherProperty); } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { if (value != null) { var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(OtherProperty); var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null); if (value.Equals(otherPropertyValue)) { return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); } } return ValidationResult.Success; } }
  • 18. Models - DataAnnotations - Model State [AllowAnonymous] [HttpPost] public JsonResult SignUp(RegisterModel model) { if (ModelState.IsValid)//Checks all data annotations based on their values { //TODO: } return Json(new { success = false, errors = ModelState.Keys.SelectMany(k => ModelState[k].Errors) .Select(m => m.ErrorMessage).ToArray() }); }
  • 19. Models - DataAnnotations - Model State - Extension Model State can be easily extended with IValidatableObject interface. Custom validation logic can be written while implementing interface method “Validate”. public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Mobile != null && !Mobile.StartsWith("91")) { yield return new ValidationResult("India country code is required", new[] { "Mobile" }); } } The order of operations for the IValidatableObject to get called: 1. Property attributes 2. Class attributes 3. Validate interface If any of the steps fail it will return immediately and not continue processing.
  • 20. Model State can be modified before sending final result to view. ModelState.Remove("Id"); // Removes validation error for this property if exists ModelState.AddModelError("<Property>", "<Message>"); try { ... } catch { ModelState.AddModelError("", "Throttling limit is reached."); return; } Models - DataAnnotations - Model State - Advance
  • 21. Views Views - Layouts, Views, Partial Views Passing Data into Views Razor - HTML Helpers - Default, Custom; Sections; ViewEngine Customization
  • 22. Views - Conventional Structure
  • 23. Views - Layout with ViewStart Layout is master page Layout can be configured for each view - using ViewStart.cshtml Layout can be configured for view folder - creating ViewStart.cshtml in that folder Layout can be configured in each view individually with setting Layout property Nested Layout can be configured - Parent/Child or Header/Footer/LeftBar/RightBar
  • 24. Views - View and Partial View View is Razor template - HTML snippet. A view can’t have views Partial View is also Razor template - HTML snippet - Reusable. A view can have partial views. Rendering Partial Views: 1. Html.Partial - Returns string, can be manipulated later 2. Html.Action - Returns string, can be manipulated later, cacheable 3. Html.RenderPartial - Returns void, content will be written with parent view into stream directly, gives better performance. 4. Html.RenderAction - Returns void, content will be written with parent view into stream directly, gives better performance, cacheable.
  • 25. Views - Passing Data into View ViewData - Dictionary, needs casting, life: Action to View ViewBag - dynamic, doesn’t need casting, ViewData wrapper, life: Action to View Session - dictionary, needs casting, life: across application TempData - dictionary, needs casting, Session wrapper, life: Action to any action Model - Passing model in view argument - Strongly Typed View
  • 26. Razor
  • 27. Razor - @ Razor code is C#, so all conventions and features are inherited
  • 28. Razor - @ @{model.property = 20;} @model.property => 20 @model.property / 10 => 20 / 10 @(model.property / 10) => 2 [email protected] => text@20 text@(model.property) => text2 @my_twitter_handle => error @@my_twitter_handle => @my_twitter_handle
  • 29. Razor - Html Helpers Html.BeginForm Html.EndForm Html.TextBox/Html.TextBoxFor Html.TextArea/Html.TextAreaFor Html.Password/Html.PasswordFor Html.Hidden/Html.HiddenFor Html.CheckBox/Html.CheckBoxFor Html.RadioButton/Html.RadioButtonFor Html.DropDownList/Html.DropDownListFor Html.ListBox/Html.ListBoxFor
  • 30. Razor - Custom Html Helper A method that returns IHtmlString (4.0) or MvcHtmlString (before 4.0) 1. Static Method that returns above return type 2. Extension method 3. @helper
  • 31. Razor - Custom Html Helper A method that returns IHtmlString (4.0) or MvcHtmlString (before 4.0) 1. Static Method that returns above return type 2. Extension method 3. @helper
  • 33. Views - Default Locations
  • 34. Views - View Engine Customization There are two ways: 1. Override existing view engines - Razor or WebForms 2. Create new engine with IViewEngine and IView public interface IViewEngine { ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache); ViewEngineResult FindView(ControllerContext controllerContext, string viewName,string masterName, bool useCache); void ReleaseView(ControllerContext controllerContext, IView view); } public interface IView { void Render(ViewContext viewContext, TextWriter writer); }
  • 35. Security There are two kind of securities that will be taken care while building views: 1. XSS 2. CSRF
  • 36. Security - XSS Injecting script that steals sensitive informations like cookies etc. 1. Someone hacked view rendering data - always render encoded html or use AntiXSS 1. System allows to enter scripts/html data - always render encoded html or use AntiXSS Attributes that allows html content posting: 1. ValidateInput - allows html for any property 2. AllowHtml - allows html for specific property
  • 42. Routing - Custom Route Constraint
  • 43. Routing - Custom Route Handler
  • 44. Routing - When is is not applicable > Existence of Physical File that Matches The URL/Route Pattern How to handle those requests: routes.RouteExistingFiles = true; > Restriction of Content like images, css and styles. [ContentAuthorize] public FileResult Index() { return File(Request.RawUrl, "image/jpeg"); } > Securing Specific Folders routes.IgnoreRoute("Content/{*relpath}"); > How to prevent routing from handling requests for the WebResource.axd file routes.Ignore("{resource}.axd/{*pathInfo}");
  • 45. Routing - Attribute Routing New Feature in MVC 5 Homework
  • 48. Filters - What How to modify default processing execution of Request/Response lifecycle? Example: public ActionResult Index() { if(!IsAuthorized()) { //Stop processing and return error } return View(); } MSDN says: “ Sometimes you want to perform logic either before an action method is called or after an action method runs. To support this, ASP.NET MVC provides 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. “ Filters are just Attributes.
  • 49. Filters - Attributes Attributes are meta data that contains custom logic that will be executed at given points. Custom Attributes public class HelpAttribute : Attribute { public HelpAttribute() { } public String Description{get;set;} } [Help(Description = "This is user class contains all information about users and their business flow")] public class User { [Help(Description = "This value is used in Authenticate() method.")] public string UserName {get;set;} [Help(Description = "This value is used in Authenticate() method.")] public string Password {get;set;} [Help(Description = "This method requires UserName and Password field. So please set those fields before calling this method.")] public bool Authenticate() { return true; } }
  • 50. Filters - Attributes public class HelpDocument<T> { private void Print(Attribute attr) { var ha = attr as HelpAttribute; if (ha != null) { Console.WriteLine(ha.Description); } } public void Build(T bo) { //Querying Class Attributes foreach (Attribute attr in type.GetCustomAttributes(true)) { Print(attr); } //Querying Class-Method Attributes foreach(MethodInfo method in type.GetMethods()) { Print(attr); } //Querying Class-Field (only public) Attributes foreach(FieldInfo field in type.GetFields()) { Print(attr); } } }
  • 51. Filters - Attributes public class HelpDocument<T> { private void Print(Attribute attr) { var ha = attr as HelpAttribute; if (ha != null) { Console.WriteLine(ha.Description); } } public void Build(T bo) { //Querying Class Attributes foreach (Attribute attr in type.GetCustomAttributes(true)) { Print(attr); } //Querying Class-Method Attributes foreach(MethodInfo method in type.GetMethods()) { Print(attr); } //Querying Class-Field (only public) Attributes foreach(FieldInfo field in type.GetFields()) { Print(attr); } } }
  • 52. Filters - Types Types of Filters [http://snag.gy/DsYnt.jpg] 1. Authentication (IAuthenticationFilter, AuthenticationAttribute) - Runs first, before any other filters or the action method 2. Authorization (IAuthorizationFilter, AuthorizeAttribute) - Runs first, before any other filters or the action method 3. Action (IActionFilter, ActionFilterAttribute) - Runs before and after the action method 4. Result (IResultFilter, ActionFilterAttribute) - Runs before and after the action result is executed 5. Exception (IExceptionFilter, HandleErrorAttribute) - Runs only if another filter, the action method, or the action result throws an exception
  • 53. Filters - Extensibility There are two ways to extend filters 1. Override existing one 2. Create your own
  • 55. Filters - Extension - Authentication public class BasicAuthAttribute : ActionFilterAttribute, IAuthenticationFilter { public void OnAuthentication(AuthenticationContext filterContext) { } public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { var user = filterContext.HttpContext.User; if (user == null || !user.Identity.IsAuthenticated) { filterContext.Result = new HttpUnauthorizedResult(); } } }
  • 56. Filters - Extension - Authorization public class BlackListAuthorizeAttribute : AuthorizeAttribute { private string[] disAllowedUsers; public BlackListAuthorizeAttribute(params string[] disAllowedUsers) { this.disAllowedUsers = disAllowedUsers; } protected override bool AuthorizeCore(HttpContextBase httpContext) { bool isAuthenticated = httpContext.Request.IsAuthenticated; bool isInBlackList = disAllowedUsers.Contains(httpContext.User.Identity.Name, StringComparer.InvariantCultureIgnoreCase); return isAuthenticated && !isInBlackList; } } [BlackListAuthorize("homer", "moe")] public ActionResult Index() { return View(); }
  • 57. Filters - Extension - Action public class LoggingFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Trace.Write("(Logging Filter)Action Executing: " + filterContext.ActionDescriptor.ActionName); base.OnActionExecuting(filterContext); } public override void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext.Exception != null) filterContext.HttpContext.Trace.Write("(Logging Filter)Exception thrown"); base.OnActionExecuted(filterContext); } }
  • 58. Filters - Extension - Result public class SqlCacheAttribute : FilterAttribute, IResultFilter, IActionFilter { private string _SqlContent = ""; private string _Key = ""; private string CacheKey(ControllerContext filterContext) { string key="";//TODO: Your Logic return key; } private void CacheResult(ResultExecutingContext filterContext) { } public void OnActionExecuting(ActionExecutingContext filterContext) { _Key = CreateKey(filterContext); _SqlContent = GetCacheValue(key); if (!string.IsNullOrWhiteSpace(_SqlContent)) { filterContext.Result = new ContentResult(); } } public void OnActionExecuted(ActionExecutedContext filterContext) { if (!string.IsNullOrWhiteSpace(_SqlContent)) { filterContext.HttpContext.Response.Write(_SqlContent); return; } CacheResult(filterContext); } public void OnResultExecuting(ResultExecutingContext filterContext) { } public void OnResultExecuted(ResultExecutedContext filterContext) { } }
  • 59. Filters - Extension - Exception Limitations of HandleError 1. Not support to log the exceptions 2. Doesn't catch HTTP exceptions other than 500 3. Doesn't catch exceptions that are raised outside controllers 4. Returns error view even for exceptions raised in AJAX calls public class HandleAjaxErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { // return json data if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") { filterContext.Result = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = new { error = true, message = filterContext.Exception.Message } }; filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = 500; } return; } }
  • 60. Filters - Execution Cancellation By setting the Result property to a non-null value, further execution will be cancelled. Example: OnActionExecuting1,OnActionExecuted1, OnResultExecuting1, OnResultExecuted1 OnActionExecuting2,OnActionExecuted2, OnResultExecuting2, OnResultExecuted2 OnActionExecuting3,OnActionExecuted3, OnResultExecuting3, OnResultExecuted3 OnActionExecuting2, filterContext.Result = new RedirectResult("~/Home/Index"); //non-null value Cancelled => OnActionExecuted2, OnActionExecuting3, OnActionExecuted3
  • 61. Filters - Registration a. Global Filter - http://snag.gy/ZqdDe.jpg b. Controller Filter - Class c. Action Filter - Method
  • 62. Dependency Injection: Introduction 1. Install nuget package - Install-Package Ninject.MVC5 2. Load/Register services private static void RegisterServices(IKernel kernel) { kernel.Bind<IHomeService>().To<HomeService>(); } 1. Create controller constructor public class HomeController : Controller { IHomeService _Service; public HomeController(IHomeService service) { _Service = service; }
  • 65. Ajax - Get $.ajax({ url: '/Ajax/Index' , type: 'Get' , contentType: 'application/json; charset=utf-8' , dataType: 'json' , success: function (response) { console.log(response); alert(response); } , error: function (req, status, error) { //TODO: error handling } });
  • 66. Ajax - Post $.ajax({ url: '/Ajax/Index' , type: 'Post' , contentType: 'application/json; charset=utf-8' , dataType: 'json' , data: '{"a2":"test","a1":5}' , success: function (response) { console.log(response); alert(response); } , error: function (req, status, error) { //TODO: error handling } });
  • 68. Ajax - Unobtrusive Ajax @Ajax.ActionLink(category, "GetProductData", new { selectedCategory = category }, new AjaxOptions { UpdateTargetId = "productsTable", OnBegin = "OnAjaxRequestBegin", OnFailure = "OnAjaxRequestFailure", OnSuccess = "OnAjaxRequestSuccess", OnComplete = "OnAjaxRequestComplete"}) <script type="text/javascript"> function OnAjaxRequestBegin() { alert("This is the OnBegin Callback"); } function OnAjaxRequestSuccess(data) { alert("This is the OnSuccessCallback: " + data); } function OnAjaxRequestFailure(request, error) { alert("This is the OnFailure Callback:" + error); } function OnAjaxRequestComplete(request, status) { alert("This is the OnComplete Callback: " + status); } </script>
  • 69. Ajax - Unobtrusive Ajax AjaxOptions ajaxOptions = new AjaxOptions { UpdateTargetId = "productsTable", LoadingElementId = "loadingProducts", LoadingElementDuration = 1000, Confirm = "Do you really want to display products?" }; @using (Ajax.BeginForm("GetProductData", ajaxOptions)) { }