Q) Explain the MVC application life cycle?
MVC application life has two main phases first creating the request object and
second sending our response to the browser. There are five main steps that
happen when you make a request to an Asp.Net MVC web application.
MVC Handler
Controller
Action Result
View Result
View Engine
View
Rendering View
1) Routing:
·
Asp.net Routing is the first
step in the MVC request cycle.
·
Basically it is a pattern
matching system that matches the request’s URL against the registered URL
patterns in the Route Table.
·
When a matching pattern is found
in the Route Table, the Routing engine forwards the request to the
corresponding IRouteHandler for that request. The default one calls
the MvcHandler.
·
The routing engine returns a
404 HTTP status code against that request if the patterns are not found in the
Route Table.
·
So if the request is the first
request the first thing is to fill the routing table with routes collection. This
filling of route table happens in the global.asax file. When the application
starts, initially Application_Start method is called which is present
in Global.asax.
·
Route table is basically a
collection of routes that are defined in the route config file.
URL Routing Module:
URL Routing module is
responsible for a mapping user requests to particular controller actions.
As per user request, URL Routing Module “UrlRoutingModule” searches the route table to create “RouteData” object
If it finds the correct match
for the request, it will create a Request Context object and send a request to
MVCHandler. As soon as the match is found, the scanning of the Route Table process stops.
public static void Register
Routes(Route Collection routes){
routes.IgnoreRoute ("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url:
"{controller}/{action}/{id}",
defaults: new { controller =
"Home", action = "Index", id = UrlParameter.Optional }
);
}
}
2) MVC Handler:
รจ MvcHandler is responsible for initiating the actual processing of the ongoing requests and generating responses. MvcHandler gets information of current request through RequestContext object passed to its constructor. MVC's handler implements the IHttpHandler interface and further processes the request by using the ProcessRequest method.
protected
internal virtual void ProcessRequest(HttpContextBase httpContext)
{
SecurityUtil.ProcessInApplicationTrust(delegate
{
IController controller;
IControllerFactory factory;
this.ProcessRequestInit(httpContext, out controller,
out factory);
try
{
controller.Execute(this.RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
});
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new
CustomControllerFactory());
}
It performs logic and then
executes the result by returning a result type. The result type can be
ViewResult, RedirectToRouteResult, RedirectResult, ContentResult, JsonResult,
FileResult, and EmptyResult.
- ViewResult : Returns a view (html type page)
- RedirectResult: Redirects to another action method
- ContentResult : Returns Content (user defined)
- JsonResult : Returns a serialized JSON data
If you do not want any specific
method should not accessible through a public URL, you can mark that method
with the [NonAction] attribute.
·
ActionResult is an abstract class while ViewResult derives from the ActionResult class. ActionResult has several derived
classes like ViewResult, JsonResult, FileStreamResult, and so on.
·
ActionResult can be used to exploit polymorphism and dynamism. So if you
are returning different types of views dynamically, ActionResult is the best thing. For example in the below code snippet,
you can see we have a simple action called DynamicView. Depending on the flag (IsHtmlView) it will
either return a ViewResult or JsonResult.
public
ActionResult DynamicView()
{
if (IsHtmlView)
return View(); // returns simple ViewResult
else
return Json(); // returns JsonResult view
}
1. ViewResult - Renders a specified view to the response stream
2.
PartialViewResult - Renders a specified partial view to the response stream
3.
EmptyResult - An empty response is returned
4.
RedirectResult - Performs an HTTP redirection to a specified URL
5.
RedirectToRouteResult - Performs an HTTP redirection to a URL that is determined
by the routing engine, based on given route data
6.
JsonResult - Serializes a given ViewData object to JSON format
7.
JavaScriptResult - Returns a piece of JavaScript code that can be executed on
the client
8.
ContentResult - Writes content to the response stream without requiring a
view
9.
FileContentResult - Returns a file to the client
10.
FileStreamResult - Returns a file to the client, which is provided by a Stream
11. FilePathResult - Returns a file to the client
5) View
Result
The action method receives user input, prepares the
appropriate response data, and then executes the result by returning a result
type. The result type can be ViewResult, RedirectToRouteResult, RedirectResult,
ContentResult, JsonResult, FileResult, and EmptyResult.
6) View Engine
The first step in the execution of the View Result
involves the selection of the appropriate View Engine to render the View
Result. It is handled by the IViewEngine interface of the view engine. By default, Asp.Net MVC uses WebForm and Razor view engines. You can also register your own
custom view engine to your Asp.Net MVC application as shown below:
protected void Application_Start()
{
//Remove All
View Engine including Webform and Razor
ViewEngines.Engines.Clear();
//Register
Your Custom View Engine
ViewEngines.Engines.Add(new
CustomViewEngine());
//Other code
is removed for clarity
}
7)View
The action method may return a text string, a binary
file, or JSON formatted data. The most important Action Result is the
ViewResult, which renders and returns an HTML page to the browser by using the
current view engine.
8) Rendering View :
The final step in the MVC life
cycle is rendering the View, where the user can see what he requested and get a response.
(or)
The action method may return a text string, a binary file, or JSON formatted data. The most important Action Result is the ViewResult, which renders and returns an HTML page to the browser by using the current view engine.
The ViewResult one of the ActionResult generates
the appropriate View to the user, by parsing the Razor syntax (.cshtml) and
server-side codes into the HTML page to the Client.
ViewResult implements the
IViewEngine Interface and has some view manipulating methods such as:
ReleaseView: To release the View
FindView: Maps the appropriate View
FindPartialView
: Returns a Partial View-----------------------------------------------------------------------------------------------------------------------------
What is MVC (Model View Controller)?
MVC is an architectural pattern that separates the
representation and user interaction. It’s divided into three broader sections,
Model, View, and Controller.
The View is responsible for the look and feel.
The model represents the real-world object and provides
data to the View.
The Controller is responsible for taking the end-user request and loading the appropriate Model and View.
MVC pattern forces a separation of concerns, which
means domain model and controller logic are decoupled from the user interface
(view). As a result, maintenance and testing of the application become simpler
and easier.
ASP.NET MVC is an open-source framework built on top of the Microsoft .NET Framework to develop a web application that enables a
clean separation of code. ASP.NET MVC framework is the most customizable and
extensible platform shipped by Microsoft.
--------------------------------------------------------------------------------------------------------------------
Is MVC suitable for both Windows and Web applications?
The MVC
architecture is suited for a web application then Windows. For Windows
applications, MVP, i.e., “Model View Presenter” is more applicable. If you are using
WPF and Silverlight, MVVM is more suitable due to bindings.-----------------------------------------------------------------------------------------------------------------------------
What are the benefits of using MVC?
There
are few benefits of MVC:
Separation
of concerns is achieved as we are moving the code behind to a separate class
file. By moving the binding code to a separate class file we can reuse the code
to a great extent.
Automated UI testing is possible because now the behind code (UI interaction code) has moved to a simple .NET class. This gives us the opportunity to write unit tests and automate manual testing.
TDD: The MVC framework brings better support to
test-driven development.
Extensible and pluggable: MVC framework components
were designed to be pluggable and extensible and therefore can be replaced or
customized easier than WebForms.
Full control over application behavior: MVC
framework doesn’t use View State or server-based forms like WebForms. This
gives the application developer more control over the behaviors of the
application and also reduces the bandwidth of requests to the server.
ASP.NET features are supported MVC framework is
built on top of ASP.NET and therefore can use most of the features that ASP.NET
include such as the provider's architecture, authentication, and authorization
scenarios, membership, and roles, caching session, and more.
URL routing mechanism: MVC framework supports a
powerful URL routing mechanism that helps to build a more comprehensible and
searchable URL in your application. This mechanism helps the application to be
more addressable from the eyes of search engines and clients and can help in
search engine optimization.
-----------------------------------------------------------------------------------------------------------------------------
Is MVC different from a three-layered architecture?
|
Functionality |
Three-layered / tiered
architecture |
Model view controller
architecture |
|
Look and Feel |
User interface |
View |
|
UI logic |
User interface |
Controller |
|
Business logic
/validations |
Middle layer |
Model |
|
The request is first
sent to |
User interface |
Controller |
|
Accessing data |
Data access layer |
Data Access Laye |
-----------------------------------------------------------------------------------------------------------------------------
Q)What is the latest version of MVC?
MVC 6 is the latest version which is also termed ASP VNEXT.
What is the difference between each version of MVC
2, 3, 4, 5, and 6?
MVC
6
ASP.NET MVC and Web API have been merged into one.
Dependency injection is inbuilt and part of MVC.
Side by side - deploy the runtime and framework with
your application
Everything is packaged with NuGet, Including the .NET
runtime itself.
New JSON-based project structure.
No need to recompile for every change. Just hit save
and refresh the browser.
The compilation is done with the new Roslyn real-time
compiler.
vNext is Open Source via the .NET Foundation and is
taking public contributions.
vNext (and Rosyln) also runs on Mono, on both Mac
and Linux today.
MVC
5
One ASP.NET
Attribute-based routing
Asp.Net Identity
Bootstrap in the MVC template
Authentication Filters
Filter overrides
MVC
4
ASP.NET Web API
Refreshed and modernized default project templates
New mobile project template
Many new features to support mobile apps
Enhanced support for asynchronous methods
MVC
3
Razor
Readymade project templates
HTML 5 enabled templates
Support for Multiple View Engines
JavaScript and Ajax
Model Validation Improvements
MVC
2
Client-Side Validation
Templated Helpers
Areas
Asynchronous Controllers
Html.ValidationSummary Helper Method
DefaultValueAttribute in Action-Method Parameters
Binding Binary Data with Model Binders
DataAnnotations Attributes
Model-Validator Providers
New RequireHttpsAttribute Action Filter
Templated Helpers
Display Model-Level Errors--------------------------------------------------------------------------------------------------------------------
What are HTML helpers in MVC?
HTML helpers help you to render HTML controls in the
view. For instance, if you want to display an HTML textbox on the view, below is
the HTML helper code.
An HTML Helper is just a method that returns an HTML
string. The string can represent any type of content that you want. For
example, you can use HTML Helpers to render standard HTML tags like HTML
<input>, <button> and <img> tags etc. You can also create
your own HTML Helpers to render more complex content such as a menu strip or an
HTML table for displaying database data.
<%= Html.TextBox("LastName") %>
<%= Html.CheckBox("Married") %>
----------------------------------------------------------------------------------------------------------------------------
What is the difference between “HTML.TextBox” vs
“HTML.TextBoxFor”?
Both of them provide the same HTML output,
“HTML.TextBoxFor” is strongly typed while “HTML.TextBox” isn’t. Below is a
simple HTML code that just creates a simple textbox with “CustomerCode” as a name.
Html.TextBox("CustomerCode")
Html.TextBoxFor(m => m.CustomerCode)--------------------------------------------------------------------------------------------------------------------
What is routing in MVC?
Routing helps you to define a URL structure and map
the URL with the controller.
For instance let’s say we want that when a user
types “http://localhost/View/ViewCustomer/”, it goes to the “Customer”
Controller and invokes the DisplayCustomer action. This is defined by adding an
entry into the routes collection using the map route function. Below is the
underlined code which shows how the URL structure and mapping with controller
and action are defined.
routes.MapRoute(
"View", // Route name
"View/ViewCustomer/{id}", // URL with parameters
new { controller = "Customer", action =
"DisplayCustomer",
id = UrlParameter.Optional }); // Parameter defaults
The route mapping code is written in
"RouteConfig.cs" file and registered using "global.asax"
application start event.--------------------------------------------------------------------------------------------------------------------
Can we map multiple URLs to the same action?
Yes, you can, you just need to make two entries with
different key names and specify the same controller and action.--------------------------------------------------------------------------------------------------------------------
Explain attribute-based routing in MVC?
This is a feature introduced in MVC 5. By using the
"Route" attribute we can define the URL structure. For example, in the
below code we have decorated the "GotoAbout" action with the route
attribute. The route attribute says that the "GotoAbout" can be invoked
using the URL structure "Users/about".
Enabling attribute routing in your ASP.NET MVC5
application is simple, just add a call to routes.MapMvcAttributeRoutes() method
within RegisterRoutes() method of RouteConfig.cs file.
public class HomeController: Controller
{
[Route("Users/about")]
public
ActionResult GotoAbout()
{
return View();
}
}--------------------------------------------------------------------------------------------------------------------
What is the advantage of defining route structures
in the code?
Most of the time developers code in the action
methods. Developers can see the URL structure right up front rather than going
to the “route.config.cs” and see the lengthy codes. For instance, in the below
code the developer can see right up front that the “GotoAbout” action can be invoked
by four different URL structures.
This is much user-friendly as compared to scrolling
through the “route config.cs” file and going through the long line of code to
figure out which URL structure is mapped to which action.
public class HomeController: Controller
{
[Route("Users/about")]
[Route("Users/WhoareWe")]
[Route("Users/OurTeam")]
[Route("Users/aboutCompany")]
public
ActionResult GotoAbout()
{
return View();
}
}--------------------------------------------------------------------------------------------------------------------
What is the importance of NonActionAttribute?
All public methods of a controller class are treated
as the action method if you want to prevent this default method, then you have
to assign the public method with NonActionAttribute.
--------------------------------------------------------------------------------------------------------------------
use of the default route
{resource}.axd/{*pathinfo}?
The default route prevents requests for a web
resource file such as Web resource. axd or ScriptResource.axd from being passed
to the controller.
--------------------------------------------------------------------------------------------------------------------
What is the difference between Routing and URL
Rewriting?
Many developers compare routing to URL rewriting
since both look similar and can be used to make SEO-friendly URLs. But both the
approaches are very much different. The main difference between routing and URL
rewriting is given below:
URL rewriting is focused on mapping one URL (new
URL) to another URL (old URL) while routing is focused on mapping a URL to a
resource.
URL rewriting rewrites your old URL to a new one
while routing never rewrites your old URL to the new one but it maps to the
original route.
--------------------------------------------------------------------------------------------------------------------
How can we navigate from one view to another using a
hyperlink?
By using the Action Link method as shown in the below
code. The below code will create a simple URL that helps to navigate to the
“Home” controller and invoke the GotoHome action.
<%= Html.ActionLink("Home","Gotohome")
%> --------------------------------------------------------------------------------------------------------------------
How can we restrict MVC actions to be invoked only
by GET or POST?
We can decorate the MVC action with the HttpGet or HttpPost attribute to
restrict the type of HTTP calls. For instance, you can see in the below code snippet
the DisplayCustomer action can only be invoked by HttpGet. If we try to make
HTTP POST on DisplayCustomer, it will throw an error.
[HttpGet]
public ViewResult DisplayCustomer(int
id)
{
Customer objCustomer = Customers[id];
return View("DisplayCustomer",objCustomer);
} ----------------------------------------------------------------------------------------------------------------------------
How can we maintain sessions in MVC?
Sessions can be maintained in MVC in three ways: temp data, viewdata, and view bag.
Temp data - Helps to maintain data when you move from one controller to another controller or from one action to another action. In other words, when you redirect, temp data helps to maintain data between those redirects. It internally uses session variables. The life of TempData is very short and lies only until the target view is fully loaded. But you can persist data in TempData by calling the Keep() method after request completion
TempData is a dictionary object that is derived from
TempDataDictionary class and stored in short lives sessions.
public TempDataDictionary TempData { get; set; }
TempData is a property of ControllerBase class.
TempData is used to pass data from current requests
to subsequent requests (means redirecting from one page to another).
Its life is very short and lies only till the
target view is fully loaded.
It’s required typecasting for getting data and check
for null values to avoid an error.
It is used to store only one-time messages like
error messages, validation messages. To persist data with TempData refer to this
article: Persisting Data with TempData
View data - Helps to maintain data when you move
from controller to view.
ViewData is a dictionary object that is derived from
ViewDataDictionary class.
public ViewDataDictionary ViewData { get; set; }
ViewData is a property of ControllerBase class.
ViewData is used to pass data from the controller to the corresponding view.
Its life lies only during the current request.
If redirection occurs then its value becomes null.
It’s required typecasting for getting data and check
for null values to avoid an error.
View Bag - It’s a dynamic wrapper around view data.
When you use the View bag type, casting is not required. It uses the dynamic keyword
internally.
ViewBag is a dynamic property that takes advantage
of the new dynamic features in C# 4.0.
Basically, it is a wrapper around the ViewData and is also used to pass data from the controller to the corresponding view.
public Object ViewBag { get; }
ViewBag is a property of ControllerBase class.
Its life also lies only during the current request.
If redirection occurs then its value becomes null.
It doesn’t require typecasting for getting data.
Session variables - By using session variables we
can maintain data from any entity to any entity.
Session:
In ASP.NET MVC, Session is a property of Controller
class whose type is HttpSessionStateBase.
public HttpSessionStateBase Session { get; }
The session is also used to pass data within the ASP.NET
MVC application and Unlike TempData, it persists for its expiration time (by
default session expiration time is 20 minutes but it can be increased).
The session is valid for all requests, not for a single
redirect.
It’s also required typecasting for getting data and
check for null values to avoid an error.
Hidden fields and HTML controls - Helps to maintain data from UI to controller only. So you can send data from HTML controls or hidden fields to the controller using POST or GET HTTP methods.
|
Maintains
data between |
ViewData/ViewBag |
TempData |
Hidden
fields |
Session |
|
Controller
to Controller |
No |
Yes |
No |
Yes |
|
Controller
to View |
Yes |
No |
No |
Yes |
|
View
to Controller |
No |
No |
Yes |
Yes |
--------------------------------------------------------------------------------------------------------------------
What is the difference between TempData and ViewData?
“TempData”
maintains data for the complete request while “ViewData” maintains data only
from the Controller to the view.
Does
“TempData” preserve data in the next request also?
“TempData”
is available throughout the current request and in the subsequent request, it’s available depending on whether “TempData” is read or not.
So if
“TempData” is once read it will not be available in the subsequent request.
What is the
use of Keep and Peek in “TempData”?
Once
“TempData” is read in the current request it’s not available in the subsequent
request. If we want “TempData” to be read and also available in the subsequent
request then after reading we need to call the “Keep” method as shown in the code
below.
@TempData["MyData"];
TempData.Keep("MyData");
The more
shortcut way of achieving the same is by using “Peek”. This function helps to
read as well advices MVC to maintain “TempData” for the subsequent request.
string str =
TempData.Peek("Td").ToString();
If you want
to read more in detail you can read from this detailed blog on MVC Peek and
Keep.--------------------------------------------------------------------------------------------------------------------
What are partial views in MVC?
A partial view is a reusable view (like a user control) that
can be embedded inside another view.
How did you create a partial view and consume it
When you add a view to your project you need to check the “Create
partial view” check box.
Add View
View name:
Create a partial view(.ascx)
Create a strongly-typed view
Once the partial view is created you can then call the
partial view in the main view using the Html.RenderPartial method as shown in
the below code snippet:
<body>
<div>
<% Html.RenderPartial("MyView"); %>
</div>
</body>--------------------------------------------------------------------------------------------------------------------
Q)How can we do validations in MVC?
One of the easiest ways of doing validation in MVC
is by using data annotations. Data annotations are nothing but attributes that
can be applied to model properties. For example, in the below code snippet we
have a simple Customer class with a property customer code.
Data Annotation attribute classes are present in
System.ComponentModel.DataAnnotations namespace and are available to Asp.net
projects like Asp.net web application & website, Asp.net MVC, Web forms, and
also to Entity framework ORM models. Data Annotations help us to define the
rules to the model classes or properties for data validation and displaying
suitable messages to end-users.
This customer code property is tagged with a Required
data annotation attribute. In other words, if this model is not provided
customer code, it will not accept it.
public class Customer
{
[Required(ErrorMessage="Customer code is required")]
public
string CustomerCode
{
set;
get;
}
}
In order to display the validation error message, we
need to use the ValidateMessageFor method which belongs to the Html helper
class.
<% using
(Html.BeginForm("PostCustomer", "Home", FormMethod.Post))
{ %>
<%=Html.TextBoxFor(m => m.CustomerCode)%>
<%=Html.ValidationMessageFor(m =>
m.CustomerCode)%>
<input type="submit" value="Submit
customer data" />
<%}%>
Later in the controller, we can check if the model is
proper or not by using the ModelState.IsValid property and accordingly we can
take actions.
public ActionResult PostCustomer(Customer obj)
{
if
(ModelState.IsValid)
{
obj.Save();
return
View("Thanks");
}
else
{
return
View("Customer");
}
}
--------------------------------------------------------------------------------------------------------------------
Can we display all errors in one go?
Yes, we can; use the ValidationSummary method from
the Html helper class.
Ex:
[StringLength(160)]
public string FirstName { get; set; }
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]public
string Email { get; set; }
[Range(10,25)]public int Age { get; set; }
If you have created the model object yourself you
can explicitly call TryUpdateModel in your controller to check if the object is
valid or not.
TryUpdateModel(NewCustomer);
In case you want to add errors in the controller you
can use the AddModelError function.
ModelState.AddModelError("FirstName",
"This is my server-side error.");
--------------------------------------------------------------------------------------------------------------------
How can we enable data annotation validation on
client side?
It’s a two-step process: first reference the
necessary jQuery files.
<script src="<%=
Url.Content("~/Scripts/jquery-1.5.1.js") %>"
type="text/javascript"></script>
<script src="<%=
Url.Content("~/Scripts/jquery.validate.js") %>"
type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/jquery.validate.unobtrusive.js")
%>" type="text/javascript"></script>
The second step is to call the
EnableClientValidation method.
<% Html.EnableClientValidation(); %> --------------------------------------------------------------------------------------------------------------------
What is Razor in MVC?
It’s a lightweight view engine. Till MVC we had only one view type, i.e., ASPX. Razor was introduced in MVC 3. Razor is clean, lightweight, and syntaxes are easy as compared to ASPX. It is responsible for converting the server-side template into HTML markup and rendering it to the browser. It is an advanced view engine that was introduced with MVC3. This is not a new language but it is a new markup syntax. Razor has new and advances syntax that is compact, expressive, and reduces typing. Razor syntax is easy to learn and much cleaner than Web Form syntax. Razor uses @ symbol to write markup as:
Ex: <%=DateTime.Now%>
In Razor, it’s just one line of code:
@DateTime.Now
As per Microsoft, Razor is more preferred because
it’s lightweight and has simple syntaxes.
--------------------------------------------------------------------------------------------------------------------
How can you do authentication and authorization in
MVC?
You can use Windows or Forms authentication for MVC.
How to implement Windows authentication for MVC?
<authentication mode="Windows"/>
<authorization>
<deny users="?"/>
</authorization>
Then in the controller or on the action, you can use
the Authorize attribute which specifies which users have access to these
controllers and actions. Below is the code snippet for that. Now only the users
specified in the controller and action can access it.
[Authorize(Users=
@"WIN-3LI600MWLQN\Administrator")]
public class StartController : Controller
{
//
// GET:
/Start/
[Authorize(Users = @"WIN-3LI600MWLQN\Administrator")]
public
ActionResult Index()
{
return
View("MyView");
}
}
How do you implement Forms authentication in MVC?
<authentication
mode="Forms">
<forms
loginUrl="~/Home/Login"
timeout="2880"/>
</authentication>
public ActionResult Login()
{
if
((Request.Form["txtUserName"] == "Shiv") &&
(Request.Form["txtPassword"] == "Shiv@123"))
{
FormsAuthentication.SetAuthCookie("Shiv",true);
return
View("About");
}
else
{
return View("Index");
}
}
[Authorize]
PublicActionResult Default()
{
return View();
}
[Authorize]
publicActionResult About()
{
return View();
}
--------------------------------------------------------------------------------------------------------------------
How to implement AJAX in MVC?
You can implement AJAX in two ways in MVC:
AJAX libraries
jQuery
--------------------------------------------------------------------------------------------------------------------
What is the difference between ActionResult and
ViewResult?
ActionResult is an abstract class while ViewResult
derives from the ActionResult class. ActionResult has several derived classes
like ViewResult, JsonResult, FileStreamResult, and so on.
ActionResult can be used to exploit polymorphism and
dynamism. So if you are returning different types of views dynamically,
ActionResult is the best thing. For example in the below code snippet, you can
see we have a simple action called DynamicView. Depending on the flag
(IsHtmlView) it will either return a ViewResult or JsonResult.
public ActionResult DynamicView()
{
if
(IsHtmlView)
return
View(); // returns simple ViewResult
else
return
Json(); // returns JsonResult view
}
--------------------------------------------------------------------------------------------------------------------
What are the different types of results in MVC?
Note: It’s difficult to remember all the 12 types.
But some important ones you can remember for the interview are ActionResult,
ViewResult, and JsonResult. Below is a detailed list for your interest:
There 12 kinds of results in MVC, at the top is the
ActionResult class which is a base class that can have 11 subtypes as listed
below:
ViewResult - Renders a specified view to the
response stream
PartialViewResult - Renders a specified partial view
to the response stream
EmptyResult - An empty response is returned
RedirectResult - Performs an HTTP redirection to a
specified URL
RedirectToRouteResult - Performs an HTTP redirection
to a URL that is determined by the routing engine, based on given route data
JsonResult - Serializes a given ViewData object to
JSON format
JavaScriptResult - Returns a piece of JavaScript
code that can be executed on the client
ContentResult - Writes content to the response
stream without requiring a view
FileContentResult - Returns a file to the client
FileStreamResult - Returns a file to the client,
which is provided by a Stream
FilePathResult - Returns a file to the client
--------------------------------------------------------------------------------------------------------------------
What are ActionFilters in MVC?
ActionFilters help you to perform logic while an MVC
action is executing or after an MVC action has been executed.
Action filters are useful in the following
scenarios:
Implement post-processing logic before the action
happens.
Cancel a current execution.
Inspect the returned value.
Provide extra data to the action.
You can create action filters in two ways:
Inline action filter.
Creating an ActionFilter attribute.
To create an inline action attribute we need to
implement the IActionFilter interface. The IActionFilter interface has two
methods: OnActionExecuted and OnActionExecuting. We can implement
pre-processing logic or cancellation logic in these methods.
public class Default1Controller : Controller ,
IActionFilter
{
public
ActionResult Index(Customer obj)
{
return
View(obj);
}
void
IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
Trace.WriteLine("Action Executed");
}
void
IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
Trace.WriteLine("Action is executing");
}
}
The problem with the inline action attribute is that
it cannot be reused across controllers. So we can convert the inline action
filter to an action filter attribute. To create an action filter attribute we
need to inherit from ActionFilterAttribute and implement the IActionFilter
interface as shown in the below code.
public class MyActionAttribute :
ActionFilterAttribute , IActionFilter
{
void
IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
Trace.WriteLine("Action Executed");
}
void
IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
Trace.WriteLine("Action executing");
}
}
Later we can decorate the controllers on which we
want the action attribute to execute. You can see in the below code I have
decorated the Default1Controller with the MyActionAttribute class which was
created in the previous code.
[MyActionAttribute]
public class Default1Controller : Controller
{
public
ActionResult Index(Customer obj)
{
return
View(obj);
}
}
----------------------------------------------------------------------------------------------------------------------------
Custom
action filters in MVC?
There are five types of filters with ASP.NET MVC 5
and they are as follows.
Authorization Filter: It is performing before or
after the validating the request.
Action Filter: It is performing before or after
action method.
Result Filter: It is performing before or after the
action result.
Exception Filter: It is executed if there is some
exception thrown by application when performing action process. It is used to
show the error page or for logging error details.
Action
Filters
It is used to execute filter logic either before the
action method execution or after the action method execution. It completes some
task sometimes before the action runs or after the action run. There are
several tasks which should be done before or after the action execution like
logging, authentication, caching, etc.
To implement action filters, you need to create
custom action filters.
Custom
Action Filters
Now, you are going to create a Custom Action Filter
which implements the pre-processing and post-processing logic. It will inherit
from ActionFilterAttribute class and also implement IActionFilter interface.
ActionFilterAttribute contains four important
methods as in the following.
OnActionExecuting: It is called just before the
action method is going to call.
OnActionExecuted: It is called just after the action
method is called.
OnResultExecuting: It is called just before the
result is executed; it means before rendering the view.
OnResultExecuted: It is called just after the result
is executed, it means after rendering the view.
Now, it is time to add new class name as
“CustomActionFilter.cs” which is inherited from ActionFilterAttribute and also
implemented IActionFilter interface.
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using System.Web.Routing;
namespace FilterDemo
{
public
class AuthorizationPrivilegeFilter : ActionFilterAttribute
{
public
override void OnActionExecuting(ActionExecutingContext filterContext)
{
AuthorizationService _authorizeService = new
AuthorizationService();
string userId = HttpContext.Current.User.Identity.GetUserId();
if
(userId != null)
{
var result = _authorizeService.CanManageUser(userId);
if (!result)
{
filterContext.Result = new RedirectToRouteResult(new
RouteValueDictionary{{ "controller", "Account" },
{ "action", "Login" }
}); }}
else
{
filterContext.Result = new RedirectToRouteResult(new
RouteValueDictionary{{ "controller", "Account" },
{ "action", "Login" }
}); }
base.OnActionExecuting(filterContext);
}
}
}
Ex:2
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);
}
}
You can see in the above code, we are overriding the
OnActionExecuting method, it is because this will be called before the action
method executes.
Authentication->Authorization-> Action->Result
There is the following way to use your Custom Action
Filters.
As Global Filter
You need to add your filter globally, to add your
filter to the global filter. You first need to add it on the Global.asax file.
protected void Application_Start()
{
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
//otehr
code
AppConfig.Configure();
}
You can use FilterConfig.cs which is inside the
App_Start folder and as you know, App_Start is accessible globally.
public class FilterConfig
{
public
static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthorizationPrivilegeFilter());
}
}
As
Controller
You can add a filter on the controller as an attribute and the filter will be applicable to all the corresponding action methods.
As
Action
If you add the action filter on particular action as
an attribute then it will be applicable to only one of these actions.
-----------------------------------------------------------------------------------------------------------------------------
Explain MVC model binders?
Model binder maps HTML form elements to the model.
It acts as a bridge between HTML UI and MVC model. Many times HTML UI names
are different than the model property names. So in the binder, we can write the
mapping logic between the UI and the model.
ImodelBinder(Interface)
HTMLForm -> Model Binder ->MODEL
-----------------------------------------------------------------------------------------------------------------------------
Explain the concept of MVC Scaffolding?
Scaffolding is a technique in which the MVC template helps to auto-generate CRUD code. CRUD stands for creating, read, update and delete. It internally uses the "Entity" framework.
Scaffolding is a technique in which the MVC template helps to auto-generate CRUD code operations against your database effectively.
Further, you can edit or customize this auto-generated code according to your
need. Scaffolding consists of page templates, entity page templates, field page
templates, and filter templates. These templates are called Scaffold templates
and allow you to quickly build a functional data-driven Web site.
-------------------------------------------------------------------------------------------------------------------
How can we do exception handling in MVC?
In the controller, you can override the “OnException”
event and set the “Result” to the view name which you want to invoke when an error
occurs. In the below code you can see we have set the “Result” to a view named “Error”.
public class HomeController: Controller
{
protected override void OnException(ExceptionContext filterContext)
{
Exception ex = filterContext.Exception;
filterContext.ExceptionHandled = true;
var model
= new HandleErrorInfo(filterContext.Exception,
"Controller","Action");
filterContext.Result = new ViewResult()
{
ViewName = "Error",
ViewData = new ViewDataDictionary(model)
};
}
}
To display the above error in view we can use the
below code
@Model.Exception;
-----------------------------------------------------------------------------------------------------------------------------
How can you handle multiple Submit buttons pointing
to multiple actions in a single MVC view?
<form action="Action1" method=post>
<input type="submit"
name="Submit1"/>
<input type="submit"
name="Submit2">
</form>
In the above code when the end-user clicks on any of
the submit buttons it will make an HTTP POST to “Action1”.
The question from the interviewer is:-
“What if we have wanted that on the “Submit1” button click
it should invoke “Action1” and on the “Submit2” button click it should invoke
“Action2”.”
Now that we have understood the question let us
answer the question in a detailed manner. There are two approaches to solve the
above problem one is the normal HTML way and the other is the “Ajax” way.
In the HTML way we need to create two forms and
place the “Submit” button inside each of the forms. And every form’s action
will point to different / respective actions. You can see the below code the
first form is posting to “Action1” and the second form will post to “Action2”
depending on which “Submit” button is clicked.
<form action="Action1" method=post>
<input type="submit"
name="Submit1"/>
</form>
<form action="Action2" method=post>
<input type="submit"
name="Submit2">
</form>
In case the interviewer complains that the above
approach is not AJAX this is where the second approach comes in. In the Ajax
way we can create two different functions “Fun1” and “Fun1”, see the below
code. These functions will make Ajax calls by using JQUERY or any other
framework. Each of these functions is binded with the “Submit” button’s
“OnClick” events.
<Script language=javascript>
function Fun1()
{
$.post("/Action1",null,CallBack1);
}
function Fun2()
{
$.post("/Action2",null,CallBack2);
}
</Script>
<form action="/Action1" method=post>
<input type=submit name=sub1
onclick="Fun2()"/>
</form>
<form action="/Action2" method=post>
<input type=submit name=sub2
onclick="Fun1()"/>
</form>
-----------------------------------------------------------------------------------------------------------------------------
What are the different types of action filters?
1. Authorization
filters
2. Action
filters
3. Result
filters
4. Exception
filters
If we have multiple filters, what’s the sequence for
execution?
1. Authorization
filters
2. Action
filters
3. Response
filters
4. Exception
filters
--------------------------------------------------------------------------------------------------------------------
Can we create our custom view engine using MVC?
Yes, we can create our own custom view engine in
MVC.
--------------------------------------------------------------------------------------------------------------------
How to send results back in JSON format in MVC
In MVC, we have the JsonResult class by which we can
return back data in JSON format. Below is a simple sample code that returns
back a Customer object in JSON format using JsonResult.
public JsonResult getCustomer()
{
Customer
obj = new Customer();
obj.CustomerCode = "1001";
obj.CustomerName = "Shiv";
return
Json(obj,JsonRequestBehavior.AllowGet);
}
--------------------------------------------------------------------------------------------------------------------
How can we detect that an MVC controller is called by POST or GET?
To detect if the call on the controller is a POST action or a GET action we can use the Request.HttpMethod property is shown in the below code snippet.
public ActionResult SomeAction()
{
if
(Request.HttpMethod == "POST")
{
return
View("SomePage");
}
else
{
return
View("SomeOtherPage");
}
}
-----------------------------------------------------------------------------------------------------------------------------
What are bundling and minification in MVC?
Bundling and minification help us improve request
load times of a page thus increasing performance.
--------------------------------------------------------------------------------------------------------------------
How does bundling increase performance?
Web projects always need CSS and script files.
Bundling helps us combine multiple JavaScript and CSS files into a single
entity thus minimizing multiple requests into a single request.
--------------------------------------------------------------------------------------------------------------------
How can you test bundling in debug mode?
If you are in debug mode you need to set EnableOptimizations to true in the bundle config.cs file or else you will not see the bundling effect in the page requests.
BundleTable.EnableOptimizations = true;
--------------------------------------------------------------------------------------------------------------------
Explain minification and how to implement it
Minification reduces the size of script and CSS files by removing blank spaces, comments, etc. For example below is a simple javascript code with comments.
// This is test
var x = 0;
x = x + 1;
x = x * 2;
var x=0;x=x+1;x=x*2;
--------------------------------------------------------------------------------------------------------------------
How do we implement minification?
When you implement bundling, minification is
implemented by itself. In other words, the steps to implement bundling and
minification are the same.
--------------------------------------------------------------------------------------------------------------------
Explain Areas in MVC?
Areas help you to group functionalities into
independent modules thus making your project more organized. For example in the
below MVC project we have four controller classes and as time passes by if more
controller classes are added it will be difficult to manage. In bigger projects, you will end up with 100’s of controller classes making life hell for
maintenance.
--------------------------------------------------------------------------------------------------------------------
Explain the concept of the View Model in MVC?
A view model is a simple class that represents data
to be displayed on the view.
In ASP.NET MVC, ViewModel is a class that contains
the fields which are represented in the strongly-typed view. It is used to pass
data from the controller to a strongly-typed view.
ViewModel contains fields that are represented in the
view (for LabelFor, EditorFor, DisplayFor helpers)
ViewModel can have specific validation rules using
data annotations or IDataErrorInfo.
ViewModel can have multiple entities or objects from
different data models or data sources.
Ex:
Designing
ViewModel
public class UserLoginViewModel
{
[Required(ErrorMessage = "Please enter your
username")]
[Display(Name = "User Name")]
[MaxLength(50)]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter
your password")]
[Display(Name
= "Password")]
[MaxLength(50)]
public string
Password { get; set; }
}
Presenting
the viewmodel in the view
@model
MyModels.UserLoginViewModel
@{
ViewBag.Title
= "User Login";
Layout =
"~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="editor-label">
@Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</div>
<p>
<input
type="submit" value="Log In" />
</p>
</div>
}
Working
with Action
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(UserLoginViewModel user)
{
// To acces data using LINQ
DataClassesDataContext mobjentity = new
DataClassesDataContext();
if
(ModelState.IsValid)
{
try
{
var q =
mobjentity.tblUsers.Where(m => m.UserName == user.UserName &&
m.Password == user.Password).ToList();
if (q.Count
> 0)
{
return
RedirectToAction("MyAccount");
}
else
{
ModelState.AddModelError("",
"The user name or password provided is incorrect.");
}
}
catch
(Exception ex)
{
}
}
return
View(user);
}
Some
Tips for using ViewModel
In ViewModel put only those fields/data that you
want to display on the view/page.
Since view represents the properties of the
ViewModel, hence it is easy for rendering and maintenance.
Use a mapper when ViewModel becomes more complex.
--------------------------------------------------------------------------------------------------------------------
How can we use two ( multiple) models with a single
view?
Let us first try to understand what the interviewer is asking. When we bind a model with a view we use the model dropdown as shown in the below figure. In the below figure we can only select one model.
-----------------------------------------------------------------------------------------------------------------------------
Q) What is a CSRF attack and how can we prevent the
same in MVC?
CSRF stands for Cross-site request forgery. So if
you see the dictionary meaning of forgery: -
“It’s an act of copying or imitating things like a signature on a cheque, official documents to deceive the authority source for
financial gains.”
So when it comes to websites this forgery is termed CSRF (Cross-Site Request Forgery).
CSRF is a method of attacking a website where the
attacker imitates a.k.a forges as a trusted source and sends data to the site. The genuine site processes the information innocently thinking that data is coming
from a trusted source.
So a proper solution to this issue can be solved by
using tokens: -
End-user browses to the screen of the money
transfer. Before the screen is served server injects a secret token inside the
HTML screen in the form of a hidden field.
Now henceforth when the end-user sends a request back
he has to always send the secret token. This token is validated on the server.
Implementing tokens is a two-step process in MVC: -
First, apply the “ValidateAntiForgeryToken” attribute to
the action.
[ValidateAntiForgeryToken]
public ActionResult Transfer()
{
//
password sending logic will be here
return Content(Request.Form["amount"] +
" has been transferred to account "
+ Request.Form["account"]);
}
Second in the HTML UI screen call “@Html.AntiForgeryToken()”
to generate the token.
Transfer money <form action="Transfer"
method=post> Enter Amount <input type="text"
name="amount" value="" />
Enter Account number
@Html.AntiForgeryToken() <input type=submit
value="transfer money" /> </form>
So now henceforth when any untrusted source send a
request to the server it would give the below forgery error.-----------------------------------------------------------------------------------------------------------------------------
What are Url Helpers?
Url helpers allow you to render HTML links and raw
URLs. The output of these helpers is dependent on the routing configuration of
your ASP.NET MVC application.
-----------------------------------------------------------------------------------------------------------------------------
When to use _ViewStart?
When a set of views shares common settings, the
_ViewStart.cshtml file is a great place to put these common view settings. If
any view needs to override any of the common settings then that view can set
new values in common settings. This page is used to make a common layout page that will be used for multiple views.
-----------------------------------------------------------------------------------------------------------------------------
Can you change the action method name?
You can also change the action method name by using
the ActionName attribute. Now the action method will be called by the name
defined by the ActionName attribute.
[ActionName("DoAction")]
public
ActionResult DoSomething()
{
//TODO:
return
View();
}
Now, DoSomething action will be identified and
called by the name DoAction.-----------------------------------------------------------------------------------------------------------------------------
How to determine there is no error in Model State?
When server-side model validation fails, errors are
included in the ModelState. Hence, by using ModelState.IsValid property you can
verify model state. It returns true if there is no error in ModelState else
returns false.
[HttpPost]
public
ActionResult DoSomething(UserViewModel model)
{
if
(ModelState.IsValid)
{
//TODO:
}
return
View();
}-----------------------------------------------------------------------------------------------------------------------------
What is the jQuery Validation Unobtrusive plugin?
Microsoft introduced the jquery.validate.unobtrusive.js
plugin with ASP.NET MVC3 to apply data model validations to the client-side
using a combination of jQuery Validation and HTML 5 data attributes.-----------------------------------------------------------------------------------------------------------------------------
What does Database first approach in MVC through
Entity Framework?
Database First Approach works as a substitute to the
Code First as well as Model First approaches to the Entity Data Model.
Moreover, the Entity Data Model makes model codes including properties,
classes, DbContext, etc. from the database within the project. The particular
class works as the link between the controller and the database. When you
undergo MVC Certification training, you may be made familiar with the Database
first approach.
The following ways are useful to connect the database
with the application.
Database First
Code First
Model First-----------------------------------------------------------------------------------------------------------------------------
Explain GET and POST Action types:
Both these actions types are described in the MVC
tutorial.
GET Action Type:
GET is employed to request data from a specific
resource. Through all the GET requests, the URL is passed. The process is
mandatory and it can take up few overloads.
POST Action Type: The POST Action type is useful to
submit data that needs to be processed to a specific resource. Through all the
POST requests, the URL is passed that is essential and the data.-----------------------------------------------------------------------------------------------------------------------------
How to execute validation in MVC?
It is easy to execute validation in MVC applications
through the validators defined in the System.ComponentModel.DataAnnotations
namespace. Various types of validators are as follows:
Required
Range
DataType
StringLength-----------------------------------------------------------------------------------------------------------------------------
How do Views and Partial Views differ?
The view contains the layout page. Before rendering any
view, the view start page is rendered. Moreover, a view may have markup tags
such as HTML, body, title, head, and meta, etc.
Partial View does not contain the layout page. It
does not validate for a view start. cshtml. It is not allowed to place common
code for a partial view inside the view start.cshtml.page. A partial view is
specially designed to render inside the view and therefore, it does not
include any markup. It is allowed to pass a regular view to the RenderPartial
method.-----------------------------------------------------------------------------------------------------------------------------
What basic folders use the MVC template without
Areas in the ASP.NET Core project?
Following folders make use of the MVC template
without Areas:
Controllers- Default folder for application
controllers
Views- It is a folder containing a folder for each
controller as well as a particular folder shared for views utilized by multiple
views or controllers.
wwwroot- It is a publicly accessible folder of a site
comprising of subfolders of static files-----------------------------------------------------------------------------------------------------------------------------
Discuss the vital namespaces used in ASP.NET MVC?
For an MVC developer, it is better t know the
significant namespaces used in the ASP.NET MVC application. Here are they:
System.Web.Mvc:
It comprises interfaces and classes which support
the MVC pattern for ASP.NET Web applications. Moreover, it contains classes
that depict controller factories, controllers, views, partial views, action
results, and model binders.
System.Web.Mvc.Ajax:
It includes classes that support Ajax scripting within
an ASP.NET MVC application.
iii. System.Web.Mvc.Html:
It includes classes that facilitate the rendering of
HTML controls in an MVC application. It contains those classes that support
input controls, forms, partial views, links, and validation.-----------------------------------------------------------------------------------------------------------------------------
Exception or Error Handling and Logging in MVC4?
Error handling is the main concern in any
application, whether it is a web application or desktop application. Usually, we
catch the exception and log its details to database or text, XML file and also
display a user-friendly message to end-user in-place of error.
Asp.Net MVC has some built-in exception filters.
HandleError is the default built-in exception filter. Let's see how to use this
filter within your application.
HandleError
Attribute
The HandleErrorAttribute filter works only when
custom errors are enabled in the Web.config file of your application. You can
enable custom errors by adding a customErrors attribute inside the <system.web>
node, as shown below:
</system.web>
<customErrors mode="On"
defaultRedirect="Error.htm"/>
</system.web>
HandleError Attribute can be used to handle errors at the Action Method level, Controller level, and Global level.
HandleError
Attribute at Action Method Level
Simply put this attribute to the action method to
tell MVC how to react when an exception occurs.
[HandleError(ExceptionType =
typeof(System.Data.DataException), View = "DatabaseError")]
public ActionResult Index(int id)
{
var db = new
MyDataContext();
return
View("Index", db.Categories.Single(x => x.Id == id));
}
HandleError
Attribute at Controller Level
Simply put this attribute to the controller to tell
MVC how to react when an exception occurs with in the action methods of this
controller.
[HandleError(ExceptionType =
typeof(System.Data.DataException), View = "DatabaseError")]
public class HomeController : Controller
{
/* Controller
Actions with HandleError applied to them */
}
HandleError
Attribute at Global Level
You can also apply the HandleError Attribute for the
entire application by registering it as a global error handler. For registering
a global error handler, open the FilterConfig.cs file within the App_Start folder
to find the RegisterGlobalFilters method.
By default, the ASP.NET MVC template has already
registered a global HandleErrorAttribute to the GlobalFilterCollection for your
application. Here you can also add your own custom filter to the global filter
collection as well.
public static void
RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute
{
ExceptionType
= typeof(System.Data.DataException),
View =
"DatabaseError"
});
filters.Add(new HandleErrorAttribute()); //by
default added
}
Limitation
of HandleError Attribute
It has no support to log the exceptions since it
suppressed the error once it is handled.
It only catches 500 HTTP errors and doesn't catch other
HTTP errors like 404,401 etc.
It doesn't catch the errors that occur outside the
controllers like errors occur in the model.
It returns an error view even if an error occurred in AJAX
calls that are not useful on the client side. It would be great to return a
piece of JSON in AJAX exceptions.
Extending HandleError Filter for logging and
handling more errors
You can also make your custom error filter by
extending the HandleError filter. Let's see how to extend this filter to log the
exceptions and return a JSON object for AJAX calls.
public class CustomHandleErrorAttribute :
HandleErrorAttribute
{
public
override void OnException(ExceptionContext filterContext)
{
if
(filterContext.ExceptionHandled ||
!filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new
HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}
// if the
request is AJAX return JSON else view.
if
(filterContext.HttpContext.Request.Headers["X-Requested-With"] ==
"XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior =
JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message =
filterContext.Exception.Message
}
};
}
else
{
var
controllerName =
(string)filterContext.RouteData.Values["controller"];
var
actionName = (string)filterContext.RouteData.Values["action"];
var model =
new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult
{
ViewName =
View,
MasterName =
Master,
ViewData =
new ViewDataDictionary(model),
TempData =
filterContext.Controller.TempData
};
}
// log the
error by using your own method
LogError(filterContext.Exception.Message,
filterContext.Exception);
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode
= 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors
= true;
}
}``-----------------------------------------------------------------------------------------------------------------------------
Different ways of rendering layouts in Asp.Net MVC
Control
Layouts rendering by using _ViewStart file in the root directory of the Views
folder
@{
var
controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
string layout
= "";
if
(controller == "Admin")
{
layout =
"~/Views/Shared/_AdminLayout.cshtml";
}
else
{
layout =
"~/Views/Shared/_Layout.cshtml";
}
Layout =
layout;
}
Method
2: Return Layout from ActionResult
We can also override the default layout rendering by
returning the layout from the ActionResult by using the below code:
public ActionResult Index()
{
RegisterModel
model = new RegisterModel();
//TO DO:
return
View("Index", "_AdminLayout", model);
}
Method
3: Define Layout within each view on the top
We can also override the default layout rendering by
defining the layout on the view by using the below code:
@{
Layout =
"~/Views/Shared/_AdminLayout.cshtml";
}
Method 4: Adding _ViewStart file in each of the
directories
@{
Layout =
"~/Views/Shared/_AdminLayout.cshtml";
}
-----------------------------------------------------------------------------------------------------------------------------
What are Ajax helpers in Asp.net MVC?
Ajax helpers are used to creating AJAX-enabled
elements like AJAX-enabled forms and links which performs the request
asynchronously and these are extension methods of the AJAX Helper class which
exists in namespace System.Web.Asp.net MVC
Below are the options that can be configured in AJAX
helpers:
URL
Confirm
On Begin
ON Complete
On Success
on Failure
UpdateTargetID-----------------------------------------------------------------------------------------------------------------------------
Layouts, RenderBody, RenderSection, and RenderPage in
ASP.NET MVC
Layouts
are used to maintain a consistent look and feel across multiple views within the ASP.NET MVC application. As compared to Web Forms, layouts serve the same
purpose as master pages but offer a simple syntax and greater flexibility.
They are similar to master pages in traditional web forms. This is used to set the common look across the multiple pages
@{
Layout="~/Views/Shared/Testlayout1.cshtml";
}
In Asp.Net MVC, at the application level, we have
_ViewStart file within the Views folder for defining the default Layout page for
your ASP.NET MVC application. For rendering, the layout page refers to this article
Different ways of rendering layouts in Asp.Net MVC.
Styles. Render
and Scripts. Render
Style. Render is used to render a bundle of CSS files
defined within BundleConfig.cs files. Styles. Render create style tag(s) for the
CSS bundle. Like Style. Render, Scripts. Render is also used to render a bundle
of Script files by rendering script tag(s) for the Script bundle.
Note:
Styles. Render and Scripts. Render generate multiple
styles and script tags for each item in the CSS bundle and Script bundle when
optimizations are disabled.
When optimizations are enabled, Styles. Render and
Scripts. Render generate a single style and script tag to a version-stamped URL
which represents the entire bundle for CSS and Scripts.
You can enable and disable optimizations by setting the EnableOptimizations property of BundleTable class to true or false within Global. asax.cs
file as shown below.
protected void Application_Start()
{
//Other code
has been removed for clarity
System.Web.Optimization.BundleTable.EnableOptimizations
= false;
}
Sections :
They are the part of the HTML which is to be rendered on the Layout page.
@Rendersection("TestSection");
and in the child pages
@section TestSection{TestContent}
If any child page does not have a section defined, it will generate an error. To avoid that
@Rendersection("TestSection", required : false);
A section allows you to specify a region of content
within a layout. It expects one parameter which is the name of the section. If
you don’t provide that, an exception will be thrown. A section in a layout page
can be defined by using the following code.
@section header{
<h1>Header Content</h1>
}
You can render the above-defined section header on the
content page as given below:
@RenderSection("header")
By default, sections are mandatory. To make sections optional just provides the second parameter value as false, which is a Boolean value.
@RenderSection("header",false)
Note
A view can define only those sections that are
referred to in the layout page otherwise an exception will be thrown.
RenderBody
RenderBody method exists in the Layout page to
render child page/view. It is just like the ContentPlaceHolder on the master page.
A layout page can have only one RenderBody method.
@RenderBody()
RenderPage
RenderPage method also exists in the Layout page to
render another page that exists in your application. A layout page can have multiple
RenderPage methods.
@RenderPage("~/Views/Shared/_Header.cshtml")
Html.RenderPartial:
-----------------------------------------------------------------------------------------------------------------------------
ASP.NET MVC - View() vs RedirectToAction() vs
Redirect() Methods
There are many ways for returning or rendering a
view in ASP.NET MVC. Many developers got confused when to use View(),
RedirectToAction(), Redirect() and RedirectToRoute() methods. In this article,
I would like to explain the difference among "View()" and
"RedirectToAction()", "Redirect()" and
"RedirectToRoute()" methods.
The
View() Method
This method is used to generates the HTML markup to
be displayed for the specified view and sends it to the browser. This acts just
like a Server.Transfer() method in ASP.NET WebForm.
public ActionResult Index()
{
return
View();
}
[HttpPost]
public ActionResult Index(string Name)
{
ViewBag.Message = "Hi, Dot Net
Tricks";
//Like
Server.Transfer() in Asp.Net WebForm
return
MyIndex();
}
public ActionResult MyIndex()
{
ViewBag.Msg =
ViewBag.Message; // Assigned value : "PrasannaKumar"
return
View("MyIndex");
}
The
RedirectToAction() Method
This method is used to redirect to specified actions
instead of rendering the HTML. In this case, the browser receives the redirect
notification and makes a new request for the specified action. This acts just
like a Response.Redirect() in ASP.NET WebForm.
Moreover, RedirectToAction constructs a redirect URL
to a specific action/controller in your application and uses the routing table to
generate the correct URL. RedirectToAction causes the browser to receive a 302
redirect within your application and gives you an easier way to work with your
route table.
public ActionResult Index()
{
return
View();
}
[HttpPost]
public ActionResult Index(string Name)
{
ViewBag.Message = "Hi, Dot Net
Tricks";
//Like
Response.Redirect() in Asp.Net WebForm
return
RedirectToAction("MyIndex");
}
public ActionResult MyIndex()
{
ViewBag.Msg =
ViewBag.Message; // Assigned value : Null
return
View("MyIndex");
}
The
RedirectToRoute() Method
This method looks up the specified route into the
Route table that is defined in global. asax and then redirect to that
controller/action defined in that route. This also make a new request like
RedirectToAction().
public static void RegisterRoutes(RouteCollection
routes)
{
routes.MapRoute(
"MyRoute", // Route name
"Account/", // URL
new {
controller = "Account", action = "Login"} // Parameter
defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL
with parameters
new {
controller = "Home", action = "MyIndex", id =
UrlParameter.Optional } // Parameter defaults
);
}
public ActionResult Index()
{
return
View();
}
[HttpPost]
public ActionResult Index(string Name)
{
return
RedirectToRoute("MyRoute");
}
Note:
The View() method doesn't make new requests, it just
renders the view without changing URLs in the browser's address bar.
The RedirectToAction() method makes new requests and the URL in the browser's address bar is updated with the generated URL by MVC.
The Redirect() method also makes new requests and the URL in the browser's address bar is updated, but you have to specify the full
URL to redirect
Between RedirectToAction() and Redirect() methods,
best practice is to use RedirectToAction() for anything dealing with your
application actions/controllers. If you use Redirect() and provide the URL,
you'll need to modify those URLs manually when you change the routing table.
RedirectToRoute() redirects to a specific route
defined in the Route table.
-----------------------------------------------------------------------------------------------------------------------------
What is the difference between View and Partial View?
|
View |
Partial View |
|
It contains the
layout page |
It does not contain
the layout page |
|
Before any view is
rendered, the view start page is rendered |
Partial view does
not verify for a view start. cshtml. We cannot put common code for a partial
view within the view start. cshtml.page |
|
The view might have
markup tags like body, HTML, head, title, meta, etc. |
Partial view is
designed specially to render within the view, and just because of that it
does not consist of any markup |
|
The view is not
lightweight as compare to Partial View |
We can pass a
regular view to the RenderPartial method |
Caching in Asp.Net MVC with example
Caching is the most important aspect of a high-performance web application. Caching provides a way of storing frequently
accessed data and reusing that data. Practically, this is an effective way for
improving web applications’ performance.
Advantage
of Caching
Reduce hosting server round-trips
When content is cached at the client or in proxies,
it causes the minimum request to the server.
Reduce database server round-trips
When content is cached at the web server, it can eliminate
the database request.
Reduce network traffic
When content is cached at the client-side, it also
reduces the network traffic.
Avoid time-consumption for regenerating reusable
content
When reusable content is cached, it avoids the time
consumption for regenerating reusable content.
Improve performance
Since cached content reduces round-trips, network
traffic and avoid time consumption for regenerating reusable content which
causes a boost in the performance.
Key
points about Caching
Use caching for content that is accessed
frequently.
Avoid caching for content that is unique per user.
Avoid caching for content that is accessed
infrequently/rarely.
Use the VaryByCustom function to cache multiple
versions of a page based on customization aspects of the request such as
cookies, role, theme, browser, and so on.
For efficient caching use the 64-bit version of Windows
Server and SQL Server.
For database caching make sure your database server
has sufficient RAM otherwise, it may degrade the performance.
For caching of dynamic contents that change
frequently, define a short cache–expiration time rather than disabling caching.
Output
Cache Filter
The OutputCache filter allows you to cache the data that is the output of an action method. By default, this attribute filter caches the data for 60 seconds. After 60 sec, if a call was made to this action then ASP.NET MVC will cache the output again.
Enabling
Output Caching
You can enable the output caching for an action
method or controller by adding an [OutputCache] attribute as shown below:
[OutputCache(Duration=20,
VaryByParam="none")]
public ActionResult Index()
{
ViewBag.Message = DateTime.Now.ToString();
return
View();
}
The output of the Index() action method will be
cached for 20 seconds. If you will not define the duration, it will cache it
for by default cache duration 60 sec.
OutputCache
Filter Parameter
CacheProfile
Duration
Location
NoStore
SqlDependency
VaryByContentEncoding
VaryByCustom
VaryByHeader
VaryByParam
Output
Caching Location
By default, content is cached in three locations:
the webserver, any proxy servers, and the user's browser. You can control the
content's cached location by changing the location parameter of the OutputCache
attribute to any of the following values: Any, Client, Downstream, Server,
None, or ServerAndClient.
By default, the location parameter has the value Any
which is appropriate for most scenarios. But there are scenarios when you
required more control over the cached data.
Suppose you want to cache the logged-in use
information then you should cache the data on the client browser since this data is
specific to a user. If you will cache this data on the server, all the users
will see the same information that is wrong.
You should cache the data on the server which is
common to all the users and is sensitive.
Configure
Cache Location
For configuring the cache location, you need to add
the System.Web.UI namespace on your controller. You can cache the user's
personal information in his browser like as below.
[OutputCache(Duration = 7200, Location =
OutputCacheLocation.Client, VaryByParam = "none", NoStore = true)]
public ActionResult Index()
{
ViewBag.Message = "Welcome : " +
User.Identity.Name;
return
View();
}
-----------------------------------------------------------------------------------------------------------------------------
Securing Asp.Net MVC Application by using Authorize
Attribute
Authorization is the process of determining the
rights of an authenticated user for accessing the application's resources. The
Asp.Net MVC Framework has an AuthorizeAttribute filter for filtering the
authorized user to access a resource.
Properties Description
Roles Gets or
sets the roles required to access the controller or action method.
Users Get or
set the user names required to access the controller or action method.
Filtering Users by Users Property
Suppose you want to allow the access of AdminProfile to only PrasannaK users then you can specify the authorized user's list to Users property as shown below.
[Authorize(Users = "Prasanna,K")]
public ActionResult AdminProfile()
{
return
View();
}
Filtering Users by Roles Property
Suppose you want to allow the access of AdminProfile
action to only Admin and SubAdmin roles then you can specify the authorize
roles list to Users property as shown below.
[Authorize(Roles = "Admin,SubAdmin")]
public ActionResult AdminProfile()
{
return
View();
}
-----------------------------------------------------------------------------------------------------------------------------
Custom
Authentication and Authorization in ASP.NET MVC
When
standard types of authentication do not meet your requirements, you need to
modify an authentication mechanism to create a custom solution. A user context
has a principle that represents the identity and roles of that user. A user
is authenticated by its identity and assigned roles to a user determine about
authorization or permission to access resources.
User
Context
Principle
Identity
Roles
ASP.NET
provides IPrincipal and IIdentity interfaces to represents the identity and
role for a user. You can create a custom solution by evaluating the IPrincipal
and IIdentity interfaces which are bound to the HttpContext as well as the
current thread.
public class CustomPrincipal : IPrincipal
{
public
IIdentity Identity { get; private set; }
public bool
IsInRole(string role)
{
if
(roles.Any(r => role.Contains(r)))
{
return true;
}
else
{
return false;
}
}
public
CustomPrincipal(string Username)
{
this.Identity
= new GenericIdentity(Username);
}
public int
UserId { get; set; }
public string
FirstName { get; set; }
public string
LastName { get; set; }
public
string[] roles { get; set; }
}
Now you can put these CustomPrincipal objects into
the thread’s current principle property and into the HttpContext’s User
property to accomplish your custom authentication and authorization process.
ASP.NET
Forms Authentication
ASP.NET forms authentication occurs after IIS
authentication is completed. You can configure forms authentication by using
forms element within the web.config file of your application. The default
attribute values for forms authentication are shown below:
<system.web>
<authentication mode="Forms">
<forms
loginUrl="Login.aspx"
protection="All"
timeout="30"
name=".ASPXAUTH"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="default.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false"
/>
</authentication>
</system.web>
The
FormsAuthentication class creates the authentication cookie automatically when
SetAuthCookie() or RedirectFromLoginPage() methods are called. The value of the
authentication cookie contains a string representation of the encrypted and
signed FormsAuthenticationTicket object.
You can
create the FormsAuthenticationTicket object by specifying the cookie name,
version of the cookie, directory path, issue date of the cookie, expiration
date of the cookie, whether the cookie should be persisted, and optionally user-defined
data as shown below:
FormsAuthenticationTicket ticket = new
FormsAuthenticationTicket(1,
"userName",
DateTime.Now,
DateTime.Now.AddMinutes(30), // value of time
out property
false, // Value
of IsPersistent property
String.Empty,
FormsAuthentication.FormsCookiePath);
string encryptedTicket =
FormsAuthentication.Encrypt(ticket);
Custom Authorization
ASP.NET MVC provides an Authorization filter to authorize a user. This filter can be applied to an action, a controller, or even globally. This filter is based on the AuthorizeAttribute class. You can customize this filter by overriding OnAuthorization() method as shown below:
public class
CustomAuthorizeAttribute : AuthorizeAttribute
{
public string
UsersConfigKey { get; set; }
public string
RolesConfigKey { get; set; }
protected
virtual CustomPrincipal CurrentUser
{
get { return
HttpContext.Current.User as CustomPrincipal; }
}
public
override void OnAuthorization(AuthorizationContext filterContext)
{
if
(filterContext.HttpContext.Request.IsAuthenticated)
{
var
authorizedUsers = ConfigurationManager.AppSettings[UsersConfigKey];
var
authorizedRoles = ConfigurationManager.AppSettings[RolesConfigKey];
Users =
String.IsNullOrEmpty(Users) ? authorizedUsers : Users;
Roles =
String.IsNullOrEmpty(Roles) ? authorizedRoles : Roles;
if
(!String.IsNullOrEmpty(Roles))
{
if
(!CurrentUser.IsInRole(Roles))
{
filterContext.Result = new
RedirectToRouteResult(new
RouteValueDictionary(new { controller =
"Error", action = "AccessDenied" }));
//
base.OnAuthorization(filterContext); //returns to login url
}
}
if
(!String.IsNullOrEmpty(Users))
{
if
(!Users.Contains(CurrentUser.UserId.ToString()))
{
filterContext.Result = new
RedirectToRouteResult(new
RouteValueDictionary(new { controller =
"Error", action = "AccessDenied" }));
//
base.OnAuthorization(filterContext); //returns to login url
}
}
}
}
}
User Authentication
A user
will be authenticated if IsAuthenticated property returns true. For
authenticating a user you can use one of the following two ways:
Thread.CurrentPrincipal.Identity.IsAuthenticated
HttpContext.Current.User.Identity.IsAuthenticated
Designing Data Model
Now it’s
time to create data access model classes for creating and accessing Users and
Roles as shown below:
public class User
{
public int UserId { get; set; }
[Required]
public String Password { get; set; }
public String
FirstName { get; set; }
public String LastName { get; set; }
public
Boolean IsActive { get; set; }
public DateTime CreateDate { get; set; }
public
virtual ICollection<Role> Roles { get; set; }
}
public class Role
{
public int RoleId { get; set; }
[Required]
public string
RoleName { get; set; }
public string Description { get; set; }
public
virtual ICollection<User> Users { get; set; }
}
Defining Database Context with
Code First Mapping between User and Role
Using
Entity Framework code-first approach, create a DataContext having User and Role
entities with its relational mapping details as shown below:
public class DataContext : DbContext
{
public
DataContext()
:
base("DefaultConnection")
{
}
protected
override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(u
=> u.Roles)
.WithMany(r=>r.Users)
.Map(m =>
{
m.ToTable("UserRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
}
public
DbSet<User> Users { get; set; }
public
DbSet<Role> Roles { get; set; }
}
Code First Database Migrations
With the
help of entity framework code, the first database migrations create the database
named Security in the SQL Server. Run the following command through the
Visual Studio Package Manager Console to migrate your code into the SQL Server
database.
protected override void
Seed(Security.DAL.DataContext context)
{
Role role1 =
new Role { RoleName = "Admin" };
Role role2 = new Role { RoleName = "User" };
User user1 = new User { Username = "admin", Email = "admin@ymail.com", FirstName = "Admin", Password = "123456", IsActive = true, CreateDate = DateTime.UtcNow, Roles = new List() };
User user2 = new User { Username = "user1", Email = "user1@ymail.com", FirstName = "User1", Password = "123456", IsActive = true, CreateDate = DateTime.UtcNow, Roles = new List() };
user1.Roles.Add(role1);
user2.Roles.Add(role2);
context.Users.Add(user1);
context.Users.Add(user2);
}
When the above three commands will be executed
successfully, as shown above, the following database will be created in your SQL
Server.
public class LoginViewModel
{
[Required]
[Display(Name
= "User name")]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name
= "Password")]
public string Password { get; set; }
[Display(Name
= "Remember me?")]
public bool
RememberMe { get; set; }
}
public class CustomPrincipalSerializeModel
{
public int
UserId { get; set; }
public string
FirstName { get; set; }
public string
LastName { get; set; }
public
string[] roles { get; set; }
}
Forms Authentication Initialization
public class AccountController : Controller
{
DataContext
Context = new DataContext();
//
// GET:
/Account/
public
ActionResult Index()
{
return
View();
}
[HttpPost]
public
ActionResult Index(LoginViewModel model, string returnUrl = "")
{
if
(ModelState.IsValid)
{
var user =
Context.Users.Where(u => u.Username == model.Username && u.Password
== model.Password).FirstOrDefault();
if (user !=
null)
{
var roles=user.Roles.Select(m => m.RoleName).ToArray();
CustomPrincipalSerializeModel serializeModel =
new CustomPrincipalSerializeModel();
serializeModel.UserId = user.UserId;
serializeModel.FirstName = user.FirstName;
serializeModel.LastName = user.LastName;
serializeModel.roles = roles;
string
userData = JsonConvert.SerializeObject(serializeModel);
FormsAuthenticationTicket authTicket = new
FormsAuthenticationTicket(
1,
user.Email,
DateTime.Now,
DateTime.Now.AddMinutes(15),
false, //pass
here true, if you want to implement remember me functionality
userData);
string
encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie
faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
if(roles.Contains("Admin"))
{
return
RedirectToAction("Index", "Admin");
}
else if
(roles.Contains("User"))
{
return
RedirectToAction("Index", "User");
}
else
{
return
RedirectToAction("Index", "Home");
}
}
ModelState.AddModelError("",
"Incorrect username and/or password");
}
return
View(model);
}
[AllowAnonymous]
public
ActionResult LogOut()
{
FormsAuthentication.SignOut();
return
RedirectToAction("Login", "Account", null);
}
}
public class MvcApplication :
System.Web.HttpApplication
{
protected
void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer<DataContext>(new
DataContextInitilizer());
}
protected
void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie
authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if
(authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
CustomPrincipalSerializeModel serializeModel =
JsonConvert.DeserializeObject<CustomPrincipalSerializeModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.UserId = serializeModel.UserId;
newUser.FirstName = serializeModel.FirstName;
newUser.LastName = serializeModel.LastName;
newUser.roles = serializeModel.roles;
HttpContext.Current.User = newUser;
}
}
}
Base Controller
for Accessing Current User
Create a base controller for accessing your User data in your all controller. Inherit, your all controller from this base controller to access user information from the user context.
public
class BaseController: Controller
{
protected virtual new CustomPrincipal User
{
get { return HttpContext.User as
CustomPrincipal; }
}
}
public
class HomeController : BaseController
{
//
// GET: /Home/
public ActionResult Index()
{
string FullName = User.FirstName + "
" + User.LastName;
return View();
}
}
Base
View Page for Accessing Current User
Create a base class for all your views for accessing your User data in your all views as shown below:
public abstract class BaseViewPage :
WebViewPage
{
public virtual new CustomPrincipal User
{
get { return base.User as CustomPrincipal; }
}
}
public abstract class
BaseViewPage<TModel> : WebViewPage<TModel>
{
public virtual new CustomPrincipal User
{
get { return base.User as CustomPrincipal; }
}
}
Register
this class within the \Views\Web.config as the base class for all your views as
given below:
<system.web.webPages.razor>
<!--Other
code has been removed for clarity-->
<pages
pageBaseType="Security.DAL.Security.BaseViewPage">
<namespaces>
<!--Other
code has been removed for clarity-->
</namespaces>
</pages>
</system.web.webPages.razor>
Now you can access the authenticated user information on all your view in an easy and simple way as shown below in Admin View:
@{
ViewBag.Title
= "Index";
Layout =
"~/Views/Shared/_AdminLayout.cshtml";
}
<h4>Welcome : @User.FirstName</h4>
<h1>Admin DashBoard</h1>
Login View
@model Security.Models.LoginViewModel
@{
ViewBag.Title
= "Index";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div
class="form-horizontal">
<h4>User Login</h4>
<hr />
@Html.ValidationSummary(true)
<div
class="form-group">
@Html.LabelFor(model => model.Username, new
{ @class = "control-label col-md-2" })
<div
class="col-md-10">
@Html.EditorFor(model => model.Username)
@Html.ValidationMessageFor(model =>
model.Username)
</div>
</div>
<div
class="form-group">
@Html.LabelFor(model
=> model.Password, new { @class = "control-label col-md-2" })
<div
class="col-md-10">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model =>
model.Password)
</div>
</div>
<div
class="form-group">
@Html.LabelFor(model => model.RememberMe,
new { @class = "control-label col-md-2" })
<div
class="col-md-10">
@Html.EditorFor(model => model.RememberMe)
@Html.ValidationMessageFor(model =>
model.RememberMe)
</div>
</div>
<div
class="form-group">
<div
class="col-md-offset-2 col-md-10">
<input
type="submit" value="Login" class="btn
btn-default" />
</div>
</div>
</div>
}
Applying CustomAuthorize Attribute
To make secure your admin or user pages, decorate your Admin and User controllers with the CustomAuthorize attribute as defined above and specify the uses or roles to access admin and user pages.
[CustomAuthorize(Roles= "Admin")]
//
[CustomAuthorize(Users = "1")]
public class
AdminController : BaseController
{
//
// GET:
/Admin/
public
ActionResult Index()
{
return
View();
}
}
[CustomAuthorize(Roles= "User")]
//
[CustomAuthorize(Users = "1,2")]
public class
UserController : BaseController
{
//
// GET:
/User/
public
ActionResult Index()
{
return
View();
}
}
You can also specify the Roles and Users within your web.config as a key to avoid hard code values for Users and Roles at the controller level.
<add key="RolesConfigKey"
value="Admin"/>
<add
key="UsersConfigKey" value="2,3"/>
Use one of these keys within the CustomAuthorize attribute as shown below:
//[CustomAuthorize(RolesConfigKey =
"RolesConfigKey")]
[CustomAuthorize(UsersConfigKey = "UsersConfigKey")]
public class
AdminController : BaseController
{
//
// GET:
/Admin/
public
ActionResult Index()
{
return
View();
}
}
[CustomAuthorize(RolesConfigKey =
"RolesConfigKey")]
// [CustomAuthorize(UsersConfigKey =
"UsersConfigKey")]
public class
UserController : BaseController
{
//
// GET:
/User/
public
ActionResult Index()
{
return
View();
}
}
-----------------------------------------------------------------------------------------------------------------------------
What is Dependency Injection in MVC?
Dependency Injection (DI) is a design pattern that
takes away the responsibility of creating dependencies from a class thus
resulting in a loosely coupled system. In order to understand DI you need to be
aware of the following terms:
Dependency
Dependency Inversion Principle
Inversion of Control (IoC)
Dependency Injection is a way to implement IoC such
that the dependencies are “injected” into a class from some external source.
The injected dependencies can either be received as constructor parameters of a
class or can be assigned to properties of that class designed for that purpose.
Dependency Injection is a technique to separate the
creation of dependencies from the main class under consideration. Using DI you
inject the objects needed by a class
typically through a constructor. This article illustrated how DI can be used in
ASP.NET MVC controllers. For the sake of simplicity, it didn’t use any IoC
Container frameworks such as Unity, Castle Windsor, and NInject. In real-world
applications, you may use one of such frameworks to make your job easier.
There are three types of DI: Construction Injection,
Setter Injection, Interface based Injection. The Construction Injection type of
DI accepts their dependency at the constructor level it means that when creating the object of the class, their dependency passes through the constructor of the
class. It provides a strong dependency contract between objects. The Setter
Injection is also known as property injection. In this type of dependency
injection, dependency passes through public property instead of the constructor. It
allows us to pass the dependencies when required. It does not provide a strong dependency contract between objects. The interface-based dependency
injection can be achieved by creating the common interface and other classes
are implements this interface to inject the dependency. In this type of DI, we
can use either constructor injection or setter injection.
There is built-in support of dependency injection
in ASP.net Core. This supports is not limited to middleware, but also support
in Controllers, views, and model as well. There are two types of service
containers provided by the ASP.net core: Framework Services and Application
Services. The framework services are services that are provided by the ASP.net
core such as ILoggerFactory etc. The application services are the custom
services created base on our requirements.
Dependency
injection into controllers
The dependency required by the ASP.net MVC controller is requested explicitly via their constructors (Constructor injection type) and this dependency is available for the controller. Some of the dependencies are injected to only the controller action as a parameter. ASP.net core has built-in support for constructor-based dependency. The dependency required by the controller is simply adding a service type to the controller in the constructor. The ASP.net core will identify the service type and try to resolve the type. It would be a good design if the service was defined using interfaces but it is not always true.
namespace DepedencyInjectionExample.Service
{
public
interface IHelloWorldService
{
string
SaysHello();
}
public class
HelloWorldService: IHelloWorldService
{
public string
SaysHello()
{
return
"Hello ";
}
}
}
The next step is to add this service to the service
container so that when the controller is requested for service, it is available to
use. We can add the service to the service container in the ConfigureServices
method of the startup class. There are three different life options available: Transient,
Scoped, and Singleton.
public void ConfigureServices(IServiceCollection
services)
{
….
…
services.AddTransient<IHelloWorldService,
HelloWorldService>();
…
…
}
If we do not register the service to the ASP.net core
service container, it will throw the exception as follows.
Now this “HelloWorld” service is available to use in
the controller. We can inject this service as a dependency in the constructor.
using DepedencyInjectionExample.Models;
using Microsoft.AspNetCore.Mvc;
using DepedencyInjectionExample.Service;
namespace DepedencyInjectionExample.Controllers
{
public class
HomeController: Controller
{
IHelloWorldService _helloWorldService;
public
HomeController(IHelloWorldService helloWorldService)
{
_helloWorldService
= helloWorldService;
}
}
}
Once the service has been configured correctly and
injected into the controller, it should display a Hello message as expected.
Summary
Dependency injection is the design pattern that
allows us to inject the dependency to the class from the outer world rather than
creating within the class. This will help us to create loosely coupled applications
so that it has provided greater maintainability, testability, and also
reusability. There is built-in support of dependency injection in ASP.net
Core. This supports is not limited to middleware, but also support in
Controllers, views, and model as well. There are three easy steps to use
Dependency injection into ASP.net core MVC application.
Create the service
Register the service into the ConfigureService method of
the startup class, so that is available to use
Inject the service where you want to use
ASP.net core allows us to specify the lifetime for
registered services based on our requirement to use the service. The service
can either register as Singleton, Transient, or Scoped.
-----------------------------------------------------------------------------------------------------------------------------
No comments:
Post a Comment