我的控制器上有删除操作。它检查用户是否确实被允许删除。
我的问题是,如果他们不被允许删除:
我应该重定向回我的索引操作(列出他们可以删除的所有文件)并在TempData中传递一条错误消息,说“不允许您删除此资源”。
OR
我应该选择他们可以删除的所有文件,列出它们并在删除操作中显示错误吗?
最佳做法是什么?
注意:我不关心授权/身份验证。
答案 0 :(得分:0)
假设通过HTTP帖子命中删除操作,Post/Redirect/Get通常是最好的做法,以防止双重帖子,所以我选择重定向临时数据。在这种特殊情况下,双重发布可能并不危险,但在其他条件相同的情况下,选择一致性。
答案 1 :(得分:0)
使用Post / Redirect / Get,这里是filter属性(不记得我发现的实际位置):
/// <summary>
/// When a RedirectToRouteResult is returned from an action, anything in the ViewData.ModelState dictionary will be copied into TempData.
/// When a ViewResultBase is returned from an action, any ModelState entries that were previously copied to TempData will be copied back to the ModelState dictionary.
/// </summary>
public class ModelStateToTempDataAttribute : ActionFilterAttribute
{
public const string TempDataKey = "__MvcContrib_ValidationFailures__";
/// <summary>
/// When a RedirectToRouteResult is returned from an action, anything in the ViewData.ModelState dictionary will be copied into TempData.
/// When a ViewResultBase is returned from an action, any ModelState entries that were previously copied to TempData will be copied back to the ModelState dictionary.
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = filterContext.Controller.ViewData.ModelState;
var controller = filterContext.Controller;
if (filterContext.Result is ViewResultBase)
{
//If there are failures in tempdata, copy them to the modelstate
CopyTempDataToModelState(controller.ViewData.ModelState, controller.TempData);
return;
}
//If we're redirecting and there are errors, put them in tempdata instead (so they can later be copied back to modelstate)
if ((filterContext.Result is RedirectToRouteResult || filterContext.Result is RedirectResult) && !modelState.IsValid)
{
CopyModelStateToTempData(controller.ViewData.ModelState, controller.TempData);
}
}
private void CopyTempDataToModelState(ModelStateDictionary modelState, TempDataDictionary tempData)
{
if (!tempData.ContainsKey(TempDataKey)) return;
var fromTempData = tempData[TempDataKey] as ModelStateDictionary;
if (fromTempData == null) return;
foreach (var pair in fromTempData)
{
if (modelState.ContainsKey(pair.Key))
{
modelState[pair.Key].Value = pair.Value.Value;
foreach (var error in pair.Value.Errors)
{
modelState[pair.Key].Errors.Add(error);
}
}
else
{
modelState.Add(pair.Key, pair.Value);
}
}
}
private static void CopyModelStateToTempData(ModelStateDictionary modelState, TempDataDictionary tempData)
{
tempData[TempDataKey] = modelState;
}
}
您需要做的就是使用“ModelStateToTempData”标记您的操作(在两个操作中:使用HttpGet和HttpPost进行营销)。像这样(来自我的项目的代码):
[ModelStateToTempData]
public ActionResult Login()
{
if(Request.IsAuthenticated)
{
return View("AlreadyLoggedIn");
}
return View();
}
[HttpPost, ValidateAntiForgeryToken, ModelStateToTempData]
public ActionResult Login(LoginViewModel viewModel)
{
if(ModelState.IsValid)
{
// other logic here
}
return RedirectToRoute("Login");
}
路由配置(以防万一):
routes.MapRoute("Login", "login", new { controller = "Login", action = "Login" });