2015-11-25 60 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; }