【问题标题】:Is this the correct way to save form values in MVC3?这是在 MVC3 中保存表单值的正确方法吗?
【发布时间】:2011-08-17 18:32:38
【问题描述】:

这是我的代码:

[HttpGet]
public ActionResult Register()
{
    RegisterViewModel model = new RegisterViewModel();
    using (CityRepository city = new CityRepository())
    {
        model.SelectCityList = new SelectList(city.FindAllCities().ToList(), "CityID", "CityName");
    }

    using (CountryRepository country = new CountryRepository())
    {
        model.SelectCountryList = new SelectList(country.FindAllCountries().ToList(), "CountryID", "CountryName");
    }

    return View(model);
}

[HttpPost]
public ActionResult Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        //Actually register the user here.
        RedirectToAction("Index", "Home");
    }            

    //Something went wrong, redisplay the form for correction.
    return View(model);
}

这是最好的方法还是有另一种更好的测试方法?请记住,我的数据库表/字段名称与我在模型中声明的完全不同。我必须从 ViewModel 中抓取值并将它们放入实体框架生成的类中以保存信息。

这里有什么对你大喊大叫的错误吗?

【问题讨论】:

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


    【解决方案1】:

    我使用那个模式和另一个看起来像这样的模式(重要的部分是 AutoMapper 部分):

    [HttpPost] public ActionResult Register(RegisterViewModel 模型) { if (!ModelState.IsValid) { // 重新填充 GET 中设置的任何输入或其他项 // 喜欢在顶部做,因为 ^^^ 很容易被忽略 返回视图(模型); } // 如果是编辑,拉到新实例 // 从数据库中并使用自动映射器 // 将提交的值从模型映射到实例 // 然后更新数据库中的实例 // // 值:仅在表单显示时有用 // 模型的一些属性/字段 //(否则,未显示的将是空/默认) // 如果是新的,插入 RedirectToAction("索引", "首页"); }

    【讨论】:

      【解决方案2】:

      这是我通常使用的模式。

      【讨论】:

        【解决方案3】:

        我更喜欢这种模式:
        控制器:

         [HttpGet]
                public ActionResult Index()
                {
                    var cities= (from m in db.cities select m);
                    ViewBag.Cities= cities;
        
                    var states = (from m in db.States select m);
                    ViewBag.States = states;
        
                    return View();
                }
                [HttpPost]
                 public ActionResult Index(RegisterViewModel model)
                     {
                     if (ModelState.IsValid)
                        { 
                          // Saving the data
                          return View("ActionName", model);
                        }
                return View();
            }
        


        查看:

        @Html.DropDownList("DDLCities",new SelectList(ViewBag.Cities, "CityId" , "CityName" ), new { @class = "className" })
        @Html.DropDownList("DDLStates",new SelectList(ViewBag.States, "StateId" , "StateName" ), new { @class = "className" })
        

        【讨论】:

          【解决方案4】:

          建议更改[HttpGet]

          [HttpGet]
          public ActionResult Register()
          {
              // Get
              var cities = new List<City>();
              var countries = new List<Country>();
          
              using (CityRepository city = new CityRepository())
              {
                 cities = city.FindAllCities().ToList();
              }
          
              using (CountryRepository country = new CountryRepository())
              {
                 counties = country.FindAllCountries().ToList();
              }
          
              // Map.
              var aggregatedObjects = new SomePOCO(cities, countries);
              var model = Mapper.Map<SomePOCO,RegisterViewModel>(aggregatedObjects );
          
              // Return
              return View(model);
          }
          

          变更摘要:

          • 以控制器的工作有意义的方式布局您的逻辑。获取 - 地图 - 返回。正是为控制器设计的任务(按顺序)。
          • 使用 AutoMapper 为您完成繁重的 ViewModel 创建工作。

          建议更改您的[HttpPost]

          [HttpPost]
          public ActionResult Register(RegisterViewModel model)
          {
              if (!ModelState.IsValid) 
                return View(model);
          
              try
              {
                 var dbObj = Mapper.Map<RegisterViewModel,SomeDomainObj>(model);
                 _repository.Save(dbObj);
                 return RedirectToAction("Index");
              }
              catch (Exception exc)
              {
                 if (exc is BusinessError)
                    ModelState.AddModelError("SomeKey", ((BusinessError)exc).FriendlyError);
                 else
                    ModelState.AddModelError("SomeKey", Resources.Global.GenericErrorMessage);
              }
          
              return View(model);
          }
          

          变更摘要:

          • 尝试/抓住。总是需要捕获异常,无论是域异常还是低级(数据库异常)
          • 首先检查 ModelState 的有效性。正如@Cymen 所说 - 先做,以免以后忘记
          • 向 ModelState 添加例外。对具有描述性、基于资源的消息的业务错误使用自定义异常类。如果错误对用户来说太低级(外键约束等),则显示一般消息

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-17
            • 1970-01-01
            • 1970-01-01
            • 2019-02-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多