mvc controller default action - asp.net-mvc

Say I have a controller with multiple actions, is there an override to make the controller return a default action if a condition is met?
Example:
I have a checkoutcontroller and I want each action to return HttpNotFound() if e-commerce is disabled on the site, is there a better way of doing it than just doing the following:
public class CheckoutController
{
[HttpGet]
public ActionResult ViewBasket()
{
if (AppSettings.EcommerceEnabled)
{
return View();
}
else
{
return HttpNotFound();
}
}
[HttpGet]
public ActionResult DeliveryAddress()
{
if (AppSettings.EcommerceEnabled)
{
return View();
}
else
{
return HttpNotFound();
}
}
}

You can create a custom action filter that will be used for action methods inside CheckoutController.
public class CommercePermissionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (AppSettings.EcommerceEnabled)
{
base.OnActionExecuting(filterContext);
}
else
{
// Example for redirection
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "Controller", "Error" },
{ "Action", "AccessDenied" }
});
}
}
}
Then you can use this filter on each action method by
[HttpGet]
[CommercePermission]
public ActionResult ViewBasket()
Or if you want whole controller actions to have this filter,
[CommercePermission]
public class CheckoutController
You can even apply filters globally to all actions in your project.
You can find more info here.

You could create a custom action filter. This would intercept the routing to that action, apply its internal logic, and either continue to the action or interrupt it as you define in the filter. Filters can be applied to individual actions, an entire controller class, or even globally for the whole application.

Related

how to check condition if temp data has value in every controller

I am looking for the optimized way of checking if tempdata has value or not in every controller in MVC. I don't want to write in every controller, Where can I write this condition that if temp data has value then show the view else redirect to Login page.
Please create a base controller
public class BaseController : Controller
{
protected override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
var id = filterContext.Controller.TempData["id"];
if (id == null)
{
filterContext.Result = RedirectToAction("Index", "Home");
}
base.OnActionExecuting(filterContext);
}
}
After that you have to inherit the base controller on very controller.
public class CheckController : BaseController
{
public ActionResult Index()
{
TempData["id"] = 2;
return View();
}
}
Use base controller in every controller. Then check in base controller that if temp data has value then show the view else redirect to Login page.
Filter code:
public class MyCustomAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.TempData.Add("some key", "some value");
}
}
Action code:
[MyCustom]
public ViewResult Index()
{
string value = TempData["key"] as string;
return View();
}

Feature toggling MVC Web Api

Is it possible to use Feature Toggling in MVC Web APIs?
I want to restrict certain controller actions to be called until the API functionality is complete.
A suggestion could be to create a custom Feature actionfilter. Maybe like this:
public class FeatureAttribute : ActionFilterAttribute
{
public string RequiredFeature { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!Settings.Default.SomeFeature)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary {{ "Controller", "Home" }, { "Action", "Index" } });
}
base.OnActionExecuting(filterContext);
}
}
And on your controller add the attribute:
[Feature(RequiredFeature = "Somefeature")]
public ActionResult ActionNotYetReady()
{
return View();
}
This is a simple example, but would redirect users to a specific controller-action whenever the feature toggle/config setting for a given feature is turned off.

MVC Set accessibility level on a method called from ajax

I would like to protect my public method from being called by a user.
Because I'm calling the action from an ajax script I can't use any access modifiers, (private, protected etc).
Also, [HttpPost] doesn't stop the user from doing a fake request.
Anyone got a solution?
Thanks
Create an action filter that allows action methods to be called by AJAX only
namespace MyFilters
{
[AttributeUsage(AttributeTargets.Method)]
public class AjaxOnlyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 404;
filterContext.Result = new HttpNotFoundResult();
}
else
{
base.OnActionExecuting(filterContext);
}
}
}
}
Then apply this to the action method
[AjaxOnly]
public JsonResult DoSomething()
{
....

Redirect to same view

I am working on a ASP.NET MVC website and I am new to this.
I have a controller with few actions. I want to use these actions through out my website.
For example
[HttpPost]
public ActionResult MyAction(ViewModel model)
{
if (ModelState.IsValid)
{
//code is here
}
return RedirectToAction(); // redirect to same view
}
I want to redirect to same view from where request is generated. I am not sure if this is possible or not ?
Based on your comment, I would create a Controller that looks like:
public MyController : Controller
{
private ActionResult SharedMethod(SomeModel model)
{
if (ModelState.IsValid)
{
//code is here
}
// viewname is required, otherwise the view name used will be
// the original calling method (ie public1.cshtml, public2.cshtml)
return this.View("SharedViewName");
}
public ActionResult Public1(SomeModel model)
{
return this.SharedMethod(model);
}
public ActionResult Public1(SomeModel model)
{
return this.SharedMethod(model);
}
}

How to validate credential in MVC and redirect to bad login page

I want to centralize authentication that developers are free to worry about the implementation of security.
I dont want to validate the authentication at each request like
public class HomeController : BaseController
{
public ActionResult Home()
{
if (Request.IsAuthenticated == true)
{
return RedirectToAction("Home", "Member");
}
return View();
}
public ActionResult Resources()
{
if (Request.IsAuthenticated == true)
{
return RedirectToAction("Resources", "Member");
}
return View();
}
}
Thanks
You can centralized your credential validation by using a BaseController for all your controller inside your application
public class BaseSupplierFlyersController : BaseController
{
//
// GET: /SupplierFlyers/
public ActionResult Index(string culture)
{
//Some action logic here
return View("Index");
}
}
In your BaseControler
public class BaseController : Controller
{
private bool IsLoged = false;
public BaseController()
: base()
{
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!IsLoged)
{
//Redirection du bad login.
//Affect the Result to cancelled previous Action execution
filterContext.Result = new RedirectResult(string.Concat("~/", ControllerConstants.Error,"/", ActionConstants.BadLogin));
}
base.OnActionExecuting(filterContext);
}
protected override void Execute(RequestContext requestContext)
{
//Validate Credential
ValidateCredential(requestContext);
//Traitement standard
base.Execute(requestContext);
}
private void ValidateCredential(RequestContext requestContext)
{
//Logic to validate credential here
IsLoged = true; //or false
}
}
Each time an Action from a Controller is fired the BaseController will validate credential in Execute method and in OnActionExecuting you can valide if the credential are valid and than take an Action like Redirect to an other page.
Looking at the code you wrote it seems like you are missing Action Filters that are part of asp.net mvc. There is one built in called Authorize that basically requires a request to be authenticated before the controller method is invoked, but creating your own is very simple.
Also in asp.net mvc 3 you can define global filters which will be part of every action invoked on your controllers. You can find some samples here

Resources