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

问题描述:

这里是我的代码:这是在MVC3中保存表单值的正确方法吗?

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

任何在这里尖叫你的错误?

这就是我通常使用的模式。

我使用的模式和它看起来像这样(重要的部分是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"); 
} 

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

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

劝更改[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); 
} 

变更摘要:

  • 布局以这样的方式,控制器的工作是有意义的逻辑。 Get - Map - Return。控制器专为其设计的任务(按顺序)。
  • 使用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); 
} 

变更摘要:

  • try/catch语句。始终需要捕获异常,无论它们是域例外还是较低级(数据库例外)
  • 首先检查ModelState的有效性。正如@Cymen所说 - 先做,以便日后不要忘记
  • 向ModelState添加异常。使用自定义异常类来处理具有描述性,基于资源的消息的业务错误。如果错误对用户而言太低(外键约束等),则显示一条通用消息