【问题标题】:How to pass model to an action which have other parameters如何将模型传递给具有其他参数的动作
【发布时间】:2011-07-03 12:55:00
【问题描述】:

我的以下问题是,当我通过 DeleteEmployee 中的 catch 部分时,如何将 ModelStateErrors 发送给操作 Employee

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

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

【问题讨论】:

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


    【解决方案1】:

    使用TempDataModelState 持久化到多个控制器操作中。

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

    这里有一些类似的帖子

    【讨论】:

      【解决方案2】:

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

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

      return View("Employee", model);
      

      HTH。

      【讨论】:

      • 如何在返回部分传递 ID 和 name 的值?
      【解决方案3】:

      ID 和 Name 的值被封装在您传递给“View”ActionResult 的 EmployeeListModel 中:

      • 型号.ID
      • 型号.名称

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

      【讨论】:

      • 虽然 ID 和 Name 的值将存储在模型中,但我需要将这些值作为参数传递,否则 EmployeeListModel model = new EmployeeListModel (ID, projectName) in Employee 没有所需的值,因此搜索不会带来正确的值!
      • 听起来你真的很想使用 RedirectToAction。如果是这样的话,那么看看这个接受的答案 - stackoverflow.com/questions/1936/…
      【解决方案4】:

      将 ModelState 存储在 TempData 中:

      TempData["ModelState"] = ModelState;
      

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

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

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        试试下面的代码 //作为最佳实践,始终使用 Viewmodel,例如employeeViewMode 并将您的视图强输入到 viewmodel 公共类 EmployeviewModel { 公共 int id; 公共字符串名称; 公共字符串错误消息; } 公共 ActionResult Employee(int ID) { EmployeeListModel model = new EmployeeListModel(ID, projectName); EmployeviewModel vm = new EmployeviewModel(); vm.id = 模型.id; vm.name = 型号.name; if (TempData.Keys.Count() > 0) { vm.errormessage = TempData["errormessage"]; } 返回视图(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);
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-26
          • 2022-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多