Tuesday, 14 June 2016

Filters In Asp.Net MVC ( Part-2 )

Example (Built-in Filters):

[Authorize]: Create an ASP.NET MVC application and create a Controller class named “BuiltinFilterController” (Create Views for corresponding Action Methods). E.g.
using System.Web;
using System.Web.Mvc;

namespace MvcFilterApp.Controllers
{
    // [Authorize] Can be Applied here in Controller Level
    public class BuiltinFilterController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        [Authorize] // Applied in Action Level
        public ActionResult CustomAuth()
        {
            return View();
        }
        public ActionResult Login()
        {
            return View();
        }
        public ActionResult Arithmatic()
        {
            return View();
        }

   }
}

Now , as [Authorize] attribute is applied in action level Unauthorized user can not access the “CustomAuth()” action method. Other action methods can be invoked by requesting from browser. If any Unauthorized user tries to make a request to “CustomAuth()” action method then he/she should navigate to the login page to do so we have to make some settings in “Web.config” i.e.

  <system.web>
      <compilation debug="true" targetFramework="4.5"/>
      <httpRuntime  targetFramework="4.5"/>
          <authentication  mode="Forms">
            <forms  loginUrl="~/CustomFilter/Login" timeout="1"/>
          </authentication>
    </system.web>

[HandleError]:
namespace MvcFilterApp.Controllers
{
    [HandleError]
    public class BuiltinFilterController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult CustomAuth()
        {
            return View();
        }
        public ActionResult Login()
        {
            return View();
        }
        public ActionResult Arithmatic()
        {
            int u = Convert.ToInt32("");//Format Exception generated here
            return View();
        }
    }
}

Now, we need a setting in “Web.config”  for viewing  the default error page (Error.cshtml) which is inside the “shared” folder if any unhandeled error is going to happen during processing the request.
                <system.web>
                       <customErrors mode="On"/>
                </system.web>

By this setting we will navigate to the default Error.cshtml page if any unhandled error is going to happen. And this page will appear for all action methods. That means it is common to all action methods. If you want different error page to appear then create another View under “Shared” folder as “FormatError.cshtml” as follows :

@{
    ViewBag.Title = "Format";
}

<h2>Format Exception</h2>
<h1>Format Exception ... !!! Place code in correct Format .....</h1>

Then for the action level define the  [HandleError] attribute as follows :

namespace MvcFilterApp.Controllers
{
    [HandleError]
    public class BuiltinFilterController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult CustomAuth()
        {
            return View();
        }
        public ActionResult Login()
        {
            return View();
        }
        [HandleError(ExceptionType = typeof(FormatException),
                                                                           View = "FormatError")]
        public ActionResult Arithmatic()
        {
            int u = Convert.ToInt32("");//Format Exception generated here
            return View();
        }

   }
}

Now, for the Arithmatic() action method we will get the “FormatError.cshtml” error page and for other action methods we will get the “Error.cshtml” (which is default error page) if any exception is going to happen.

[OutputCache]:
For testing this decorate the action method with the [OutputCache] attribute. For e.g.

public class BuiltinFilterController : Controller
{
        [OutputCache(Duration = 10)]
        public ActionResult Index()
        {
            ViewBag.Time = DateTime.Now;
            return View();
        }
        public ActionResult Login()
        {
            return View();
        }
}

Create a View for the Index Action as “Index.cshtml” and write the following code as follows :

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
<h1>@ViewBag.Time</h1>

Now ,after running the application we can get the cached time which will be updated in every 10 Secs.

[ChildActionOnly]:
For this example design a PartialView named “_ChildAction.cshtml” i.e.

<h1>@ViewBag.msg</h1>

 Then define the controller as follows :

 public class BuiltinFilterController : Controller
 {
     
        public ActionResult Index()
        {
            return View();
        }
        [ChildActionOnly]
        public ActionResult ChildAction()
        {
            ViewBag.msg = "I am A Child Action.";
            return PartialView("_ChildAction");
        }
}

Now , under the View of the Index action call the child action. Because if we decorate an action with the [ChildActionOnly] then it cannot be accessed directly through browser request. Thus the code will be:

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
  
 @Html.Action("ChildAction")

[RequireHttps]:
By using this attribute we forcibly re-sent the “Http” request to “Https” request. It is generally used for the secure data transfer i.e. by this process the data is sent in the encrypted format.

public class BuiltinFilterController : Controller
{
        [RequireHttps]
        public string TestAction()
        {
            return "Hello ... This is from Test Action ...!!!";
        }
}

Now make request to this action method through the browser with applying and without applying the  [RequireHttps] attribute. You can find the difference easily.

[AllowAnonymous]:

If we consider in a case where the [Authorize] attribute is applied at the Controller level then all the action method present within the controller will be accessible by only the authorized users. But in some cases we need to access some  action methods without authorization in this case we can provide access to such action methods anonymously by using the [AllowAnonymous] attribute.

[Authorize]
public class BuiltinFilterController : Controller
{
        [AllowAnonymous]
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult EmpDetails()
        {
            return View();
        }
        public ActionResult DeptDetails()
        {
            return View();
        }        
}

In the above example we need the anonymous access to the “Index” action so we decorate the “Index” action as [AllowAnonymous] attribute. Other action methods other than “Index” cannot be accessed without  Authorization.

[OverrideAuthorization]:

If in some cases we need to provide different role to the action method(s) other than the role provided in the controller level then this task can be fulfilled by the [OverrideAuthorization] attribute.

[Authorize(Roles="Admin")]
public class BuiltinFilterController : Controller
{
        [OverrideAuthorization]
        [Authorize(Roles = "User")]
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult EmpDetails()
        {
            return View();
        }
        public ActionResult DeptDetails()
        {
            return View();
        }        
}

In the above case only Index can be accessed by the “User” role except that all other action methods are under the “Admin” role. Here the User role is provided by overriding the Admin role.

No comments:

Post a Comment