在我的ASP .NET MVC 3 Web应用程序中,我使用了很多部分视图。我在某些情况下通过正常的渲染调用
使用这些部分视图<div id="attributes">
@Html.Partial("_DeviceAttributesPartial", Model.DeviceAttributes)
</div>
在其他情况下使用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);
}
});
我试图找到一种方法来阻止用户直接进入我的部分视图ActionResults,例如:
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);
}
我偶然发现this answer只是做出了private
行动。我试了一下它似乎有效,但我对此感到不安,不知道可能会发生什么其他副作用。
所以我的问题是:
private
是否明智? POST
NB:大多数部分操作结果函数都是[HttpPost]
,所以我认为无论如何都不能访问它们。
答案 0 :(得分:3)
降低操作可见性将阻止该操作在控制器外部可用。由[HttpPost]属性修饰的动作可供所有人使用,但只能通过POST http请求,这比普通用户要做的要多。
考虑使用您不会通过POST访问的[ChildActionOnly]属性来修饰操作,而是使用[HttpPost]修饰这些操作。
答案 1 :(得分:2)
您可以创建一个过滤器,检查请求是否为ajax请求,如果不是则返回404
[AjaxResult]
然后,您可以使用
修饰控制器方法filterContext.Result = new HttpUnauthorizedResult();
根据您的具体情况,您也可以
.run(function ($http) {
$http.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
});
这将返回401而不是404。
您仍然可以使用RenderPartial并阻止对动作结果的任何非ajax请求。
在尝试自己实现之后,请务必注意,必须确保HTTP标头“X-Requested-With”设置为“XMLHttpRequest”。对于Ajax请求,这显然不是问题,但是对于angular,您需要在模块声明的末尾标记这个:
{{1}}
答案 2 :(得分:1)
将操作标记为私有会使此操作无法访问。就像行动不再存在一样。当您使用带有RenderPartial
方法的partials时,您没有调用相应的控制器操作。如果使用Html.RenderAction
调用控制器操作,则可以使用[ChildActionOnly]
属性修饰此操作。您可以查看following blog post以更好地理解两者之间的区别。