如何将模型传递给具有其他参数的动作

时间:2011-02-24 12:21:13

标签: asp.net-mvc asp.net-mvc-3

以下问题是当我浏览DeleteEmployee中的catch部分时,如何将ModelStateErrors发送到Actionee动作

   public ActionResult Employee(int ID, string Name)
    {
        EmployeeListModel model = new EmployeeListModel (ID, projectName);
        return View(model);
    }

 public ActionResult DeleteEmployee(Employee emp)
    {

        try
        {
            emp.Delete();
            return RedirectToAction("Employee", new { ID = emp.ID, Name = emp.Name });
        }

        catch (Exception e)
        {
            EmployeeListModel model = new EmployeeListModel (emp.ID, emp.Name);
            ModelState.AddModelError("Error", e.Message);
            return RedirectToAction("Employee", model);
        }
    }

使用return View(“Employee”,model);我仍然无法将ID和名称作为参数发送。

5 个答案:

答案 0 :(得分:5)

使用TempData在多个控制器操作中保留ModelState

MvcContrib有一个动作过滤器来执行此操作。 Jeremy Skinner在http://www.jeremyskinner.co.uk/2008/10/18/storing-modelstate-in-tempdata-with-aspnet-mvc/写了代码和一篇关于它的博客文章。源的链接已损坏,因此我发布了以下代码。

ModelStateToTempDataAttribute Source Code

/// <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;
    }
}

以下是一些类似的帖子

答案 1 :(得分:1)

从视图来看,模型状态字典是ViewDataDictionary的一部分,所以尝试通过viewdata访问它,至少在MVC 3中也是如此(在旧版本中也是如此)。您不需要通过模型传递它,而是以这种方式访问​​它。

但是,如果您进行重定向,我不知道是否保留模型状态错误;您可能希望直接返回响应:

return View("Employee", model);

HTH。

答案 2 :(得分:1)

ID和名称的值将被发送到您传递给“View”ActionResult的EmployeeListModel中:

  • Model.ID
  • Model.Name

注意,@ Brian是正确的,你需要使用“View”ActionResult而不是“RedirectToAction”ActionResult,否则模型状态错误将丢失。另一种方法是将模型状态存储在TempData中,这实际上是会话对象的特殊包装器。如果你需要确保你的网址正确更新,你需要使用像“RedirectToAction”ActionResult这样的东西......

答案 3 :(得分:1)

将ModelState存储在TempData中:

TempData["ModelState"] = ModelState;

然后使用动作过滤器合并ModelState,例如:

protected override void OnActionExecuted(ActionExecutedContext context)
{
    filterContext.Controller.ViewData.ModelState.Merge((ModelStateDictionary)TempData["ModelState"]);
}

希望这有帮助。

答案 4 :(得分:1)

尝试以下代码         //作为最佳实践,请始终使用Viewmodel,例如employeeViewMode并强烈键入view到viewmodel的视图         公共类EmployeviewModel         {             public int id;             公共字符串名称;             public string errormessage;         }         public ActionResult Employee(int ID)         {             EmployeeListModel model = new EmployeeListModel(ID,projectName);             EmployeviewModel vm = new EmployeviewModel();             vm.id = model.id;             vm.name = model.name;             if(TempData.Keys.Count()&gt; 0)             {                 vm.errormessage = TempData [“errormessage”];             }             return View(vm);         }

    public ActionResult DeleteEmployee(Employee emp)
    {
        try
        {
            emp.Delete();
            return RedirectToAction("Employee", new { ID = emp.ID, Name = emp.Name });
        }

        catch (Exception e)
        {
            //use TempData to store error message
            TempData["ErrorMessage"] = e.message;
            return RedirectToAction("Employee", emp.ID);
        }
    }