2015-11-25 61 views
0

我需要一些帮助。我有以下情况,我认为我做错了什么。MVC - 验证(Model.State)使用ViewModel

- 型号 “国家”

namespace App.Model 
    { 
     public class State 
     { 

      [Key] 
      [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
      public int idState { get; set; } 

      [Required(ErrorMessage = "Initials is required")] 
      public string StateInitials { get; set; } 

      [Required(ErrorMessage = "Name is required")] 
      public string StateName { get; set; } 

      [Display(Name = "Update Date")] 
      [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")] 
      public DateTime? UpdateDate { get; set; } 

      [Display(Name = "Update Responsible")] 
      public string UpdateResponsible { get; set; } 

     } //class 

    } //namespace 

- 模型 “位置”

namespace App.Model 
    { 
     public class Location 
     { 

      [Key] 
      [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
      public int idLocation { get; set; } 

      public int idState { get; set; } 

      [Required(ErrorMessage = "Name is required")] 
      public string LocationName { get; set; } 

      public string Status { get; set; } 
      public string ManagerName { get; set; } 
      public string Address { get; set; } 

      [Display(Name = "Update Date")] 
      [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")] 
      public DateTime? UpdateDate { get; set; } 

      [Display(Name = "Update Responsible")] 
      public string UpdateResponsible { get; set; } 

     } //class 

    } //namespace 

国家和位置之间的关系是一对多的,但我didn't形容这在模型上(使用导航字段)。

我有一个视图,我想编辑位置。为此,我使用以下视图模型。

- 视图模型 “LocationsViewModel”

namespace App.ViewModel 
    { 
     public class LocationsViewModel 
     { 

      public State objState { get; set; } 

      public List<Location> lstLocations { get; set; } 

     } //class 

    } //namespace 

编辑我用下​​面的控制器的位置。

namespace App.Controllers 
{ 

    public class LocationController : Controller 
    { 

    private DbContext db = new DbContext(); 

    // GET: /Location/Edit/5 
    public ActionResult Edit(int? id) 
    { 

     if (id == null) 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 

     State objState = db.States.Find(id); 

     if (objState == null) 
     { 
      return HttpNotFound(); 
     } 

     LocationsViewModel model = new LocationsViewModel(); 
     model.objState = objState; 
     model.lstLocations = getLocations(objState.idState); //I didn´t show this method here just to simplify 

     return View(model); 

    } //Edit 

    // POST: /Location/Edit/5 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Editar(LocationsViewModel model) 
    { 

     State objState = db.States.Find(model.objState.idState); 

     try 
     { 

      if (ModelState.IsValid) 
      { 

       //Saving Locations 
       foreach (Location obj in model.lstLocations) 
       { 

        Location objLocation = db.Locations.Find(obj.idLocation); 
        objLocation.LocationName = obj.LocationName; 
        objLocation.Status = obj.Status; 
        objLocation.ManagerName = obj.ManagerName; 
        objLocation.Address = obj.Address; 

        objLocation.UpdateDate = DateTime.Now; 
        objLocation.UpdateResponsible = User.Identity.Name; 
        db.Entry(objLocation).State = EntityState.Modified; 

        db.SaveChanges(); 

       } //foreach 

       return RedirectToAction("Index"); 

      } 

     } 
     catch (Exception e) 
     { 
      ModelState.AddModelError("", e.Message); 
     } 

     model.objState = objState; 
     model.lstLocations = getLocations(objState.idState); //I didn´t show this method here just to simplify 

     return View(model); 

    } //Edit 

} //class 

} //namespace 

问题/问题是:

我写了这个代码进行编辑(保存)的特定国家地区的清单。当我提交“编辑”视图时,MVC尝试验证位置列表(lstLocations)和状态(objState),但我想验证只有位置列表。

注意1.我需要传递给我的编辑视图这两个对象:objState和lstLocations。我需要objState对象,因为我在页面(视图)上向用户显示了一些State的属性。

注2: I'm得到ModelState.IsValid =假因为model.objLocation是无效的,但我不希望检查objLocation(不相关,这一观点)。我只想查看位置列表(lstLocation)

实现我的gol的最佳方法是什么?难道我做错了什么?我需要改变我的思维方式吗?

+0

使用视图模型,因为它应该被使用。 'LocationsViewModel'不应该包含你的数据模型,只是你想要在视图中的属性(它不会包含验证属性) –

回答

2

你需要两件事。首先是从ModelState中删除不想验证的对象。第二是你需要把你的代码块在if(ModelState.IsValid)块中以有效状态执行。

public ActionResult Edit(int? id) 
{ 
    //don't validate this field 
    ModelState.Remove("yourObject.property"); 

    if (ModelState.IsValid) 
    { 
     ... 
    } 
} 
+0

我不能使用'ModelState.Remove(“yourObject”)'但我们可以使用' ModelState.Remove(“yourObject.property”);'改为。 –

+0

已更新。谢谢。 – Ian

0

除了您已经选择的解决方案,我发现自定义RequiredIfAttribute有用。使用该功能,您可以根据其他条件控制是否需要某些内容,例如:

... 
public bool RequireLocationName { 
    get { 
     return !Addresses.Any(); 
    } 
} 

[RequiredIf("RequireLocationName", true)] 
public bool LocationName { get; set; }