这是在MVC3中保存表单值的正确方法吗?

时间:2011-08-17 18:32:38

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

这是我的代码:

[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中抓取值并将它们放入实体框架生成的类中以保留信息。

这里有什么东西让你觉得错了?

4 个答案:

答案 0 :(得分:1)

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

[HttpPost]
public ActionResult Register(RegisterViewModel model)
{
    if (!ModelState.IsValid)
    {
        // repopulate any input or other items set in GET
        // prefer to do at top due to ^^^ is easy to overlook
        return View(model);
    }

    // if it's an edit, pull to new instance
    // from the database and use automapper to
    // map over the submitted values from model to instance
    // then update instance in database
    //
    // VALUE: useful if form only shows
    // some of the properties/fields of model
    // (otherwise, those not shown would be null/default)

    // if it's new, insert

    RedirectToAction("Index", "Home");
}

答案 1 :(得分:0)

这是我通常使用的模式。

答案 2 :(得分:0)

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

 [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" })

答案 3 :(得分:0)

建议对[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添加例外。使用自定义异常类将业务错误与描述性的基于资源的消息一起使用。如果用户的错误级别太低(外键约束等),则显示通用消息