Declaring ActionResult Confidential to Prevent Direct Access to the URL

In my ASP.NET MVC 3 web application, I use many partial views. I use these partial views in some cases through regular rendering calls

<div id="attributes"> @Html.Partial("_DeviceAttributesPartial", Model.DeviceAttributes) </div> 

and in other cases using AJAX:

 $.ajax({ url: '@Url.Action("GetDeviceAttributes")', type: 'POST', data: { deviceID: device, deviceTypeID: devicetype, deviceModelID: devicemodel }, success: function (result) { // when the AJAX succeeds refresh the device model drop down holder $('#attributes').html(result); } }); 

I tried to find a way to prevent users from navigating directly to my partial ActionResults view, for example:

 public ActionResult GetDeviceModelList(int deviceTypeID) { var model = new EditDeviceViewModel(); var deviceType = _db.DeviceTypes.Single(t => t.ID == deviceTypeID); model.DeviceModelList = new SelectList(_db.DeviceModels.Where(m => m.DeviceType.ID == deviceType.ID), "ID", "Model"); return PartialView("_DeviceModelListPartial", model); } 

I came across this answer just to make the action private . I tried and it seemed to work, but I was embarrassed to do this without knowing what other side effects might occur.

So my questions are:

  • Is setting up private actions reasonable?
  • What other side effects may result from this?
  • How about actions available only through POST ?

NB: Most of the functions of the partial action result [HttpPost] , so I do not believe that they are available in any case.

+4
source share
3 answers

Reducing the visibility of an action will prevent access to this action outside the controller. Actions that are decorated with the [HttpPost] attribute are accessible to everyone, but only through the HTTP POST request, which slightly exceeds the average user.

Consider the design of actions using the [ ChildActionOnly ] attribute, which you will not be able to access through POST; instead, perform these actions using [HttpPost].

+3
source

You can create a filter that checks if the request is an ajax request, and if it does not return 404

 public class AjaxResult : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new HttpNotFoundResult(); } base.OnActionExecuting(filterContext); } } 

Then you can decorate your controller method

 [AjaxResult] 

Depending on your circumstances, you can also

 filterContext.Result = new HttpUnauthorizedResult(); 

This will return 401 instead of 404.

You can still use RenderPartial and block any non-jax requests for the result of the action.

After trying to implement this yourself, it is important to note that you must ensure that the HTTP header "X-Requested-With" is set to "XMLHttpRequest". With Ajax requests this is clearly not a problem, but with angular you need to mark this at the end of your module declaration:

 .run(function ($http) { $http.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'; }); 
+2
source

Labeling the private action makes this action unavailable. As if the action no longer existed. When you used particles using the RenderPartial method, you do not invoke the corresponding controller action. If you invoke a controller action using Html.RenderAction , you can decorate this action using the [ChildActionOnly] attribute. You can take a look at the next blog post to better understand the difference between the two.

+1
source

All Articles