2017-08-06 105 views
2

我在使用存儲庫,視圖模型和映射到我的ASP.Net MVC項目中實現CRUD操作時遇到問題。 「細節」(讀取關於一個對象的信息)和「索引」(讀取整個對象列表),控制器正在工作。使用存儲庫和映射實現MVC設計模式,C#

我將Model映射到ViewModel,然後在View中顯示它。但對於Create,UpdateDelete操作,我應該將ViewModel映射到Model。你能告訴我我錯在哪裏嗎?

模型

public class User 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    public string Name { get; set; } 

    [Unique] 
    [Required] 
    [MaxLength(100)] 
    public string Email { get; set; } 

    [Required] 
    public string Password { get; set; } 

    public string Phone { get; set; } 

    public bool IsAdmin { get; set; } 
} 

基地庫

public class BaseRepository<T> : IBaseRepository<T> where T : class 
{ 
    private RushHourContext db = null; 
    private DbSet<T> table = null; 

    public BaseRepository() 
    { 
     this.db = new RushHourContext(); 
     table = db.Set<T>(); 
    } 

    public BaseRepository(RushHourContext db) 
    { 
     this.db = db; 
     table = db.Set<T>(); 
    } 

    public IEnumerable<T> SelectAll() 
    { 
     return table.ToList(); 
    } 

    public T SelectByID(object id) 
    { 
     return table.Find(id); 
    } 

    public void Insert(T obj) 
    { 
     table.Add(obj); 
    } 

    public void Update(T obj) 
    { 
     table.Attach(obj); 
     db.Entry(obj).State = EntityState.Modified; 
    } 

    public void Delete(object id) 
    { 
     T existing = table.Find(id); 
     table.Remove(existing); 
    } 

    public void Save() 
    { 
     db.SaveChanges(); 
    } 
} 

接口庫

public interface IBaseRepository<T> where T : class 
{ 
    IEnumerable<T> SelectAll(); 
    T SelectByID(object id); 
    void Insert(T obj); 
    void Update(T obj); 
    void Delete(object id); 
    void Save(); 
} 

控制器

private RushHourContext _db = new RushHourContext(); 
    private IBaseRepository<User> _repository = null; 

    public UsersController() 
    { 
     this._repository = new BaseRepository<User>(); 
    } 

    public ActionResult Index() 
    { 
     if (!LoginUserSession.IsStateAdmin) 
     { 
      return RedirectToAction("Login"); 
     } 
     var users = _repository.SelectAll().ToList(); 
     var userViewModel = Mapper.Map<List<UserViewModel>>(users); 
     return View(userViewModel); 
    } 

    public ActionResult Details(int? id) 
    { 
     var users = _repository.SelectByID(id); 

     var userViewModel = Mapper.Map<UserViewModel>(users); 
     return View(userViewModel); 
    } 

    public ActionResult Create(User user) 
    { 
     var users = _repository.Insert(user); // THIS CODE HERE IS WRONG 

     var userViewModel = Mapper.Map<User>(users); 

     return View(userViewModel); 
    } 

UserViewModel

public class UserViewModel 
{ 
    public int Id { get; set; } 

    [Required(ErrorMessage = "Please enter User Name.")] 
    [Display(Name = "User Name")] 
    public string Name { get; set; } 

    [MaxLength(100)] 
    [Display(Name = "Email Address")] 
    public string Email { get; set; } 

    [Required] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    public string Phone { get; set; } 

    public bool IsAdmin { get; set; } 
} 

查看

@model RushHour.ViewModels.UserViewModel 

@{ 
    ViewBag.Title = "Create"; 
} 
<h2>Create</h2> 


<div> 
    @Html.AntiForgeryToken() 


    @using (Html.BeginForm("Create", "Users", FormMethod.Post, new { enctype = "multipart/form-data" })) 
    { 
     @Html.AntiForgeryToken() 

     <div>@Html.LabelFor(model => model.Id)</div> 
     <div>@Html.TextBoxFor(model => model.Id)</div> 
     <div>@Html.ValidationMessageFor(model => model.Id)</div> 

     <div>@Html.LabelFor(model => model.Name)</div> 
     <div>@Html.TextBoxFor(model => model.Name)</div> 
     <div>@Html.ValidationMessageFor(model => model.Name)</div> 

     <div>@Html.LabelFor(model => model.Password)</div> 
     <div>@Html.TextBoxFor(model => model.Password)</div> 
     <div>@Html.ValidationMessageFor(model => model.Password)</div> 

     <div>@Html.LabelFor(model => model.Email)</div> 
     <div>@Html.TextBoxFor(model => model.Email)</div> 
     <div>@Html.ValidationMessageFor(model => model.Email)</div> 

     <div>@Html.LabelFor(model => model.Phone)</div> 
     <div>@Html.TextBoxFor(model => model.Phone)</div> 
     <div>@Html.ValidationMessageFor(model => model.Phone)</div> 


     <div>@Html.LabelFor(model => model.IsAdmin)</div> 
     <div>@Html.TextBoxFor(model => model.IsAdmin)</div> 
     <div>@Html.ValidationMessageFor(model => model.IsAdmin)</div> 


     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    } 
</div> 
+0

「我要地圖視圖模型到模型中。」 - 正是 - 做到這一點。您遇到的問題是什麼?通常,有一個DTO,例如'UserDto',它以表單數據的形式出現。然後將其映射到您的「用戶」並重定向到該新創建索引的詳細信息頁面。 – ironstone13

+0

你能給我一些例子或鏈接。這是我第一次這樣做,我迷路了。我評論我的問題在哪裏。在我的創建控制器// var users = _repository.Insert(user); – Geya

+0

對於create函數,使用'UserViewModel'而不是'User',然後映射到'User'以保存到數據庫。 –

回答

0
  1. 你在你的Create視圖模型是你的UserViewModel並且應該傳遞給控制器​​,而不是User

  2. 您設置的模式建議用戶在輸入新用戶信息時首先在Create視圖中。因此,他們會在第一次旅行時不導入任何對象而導航到此視圖。如果是這樣的話,你需要一個無參數的構造函數來進行第一次訪問,你只需要創建一個新的UserViewModel並將它傳入。然後,在用戶創建後導航回到此視圖,這將向他們呈現一個表單,對用戶體驗非常困惑。您可能希望重定向到確認頁面或登錄頁面,並顯示用戶創建的消息。

  3. 只要您對數據進行更改,EntityFramework將不會在存儲庫上調用SaveChanges之前進行這些更改。奇怪的是,你沒有立即保存你的新用戶創建後。

DbSet.Add

DbContext.SaveChanges

0

對於創建功能使用UserViewModel代替User。然後從UserViewModel映射到User以插入到數據庫中。之後,如果要顯示保存的數據,則返回UserViewModel對象。

請嘗試下面的代碼。

[HttpPost] 
public ActionResult Create(UserViewModel userViewModel) 
{ 
    var user = new User(); 
    var newUser = Mapper.Map(userViewModel, user); 
    _repository.Insert(newUser); 
    _repository.Save(); 
    return View(userViewModel); 
} 
+0

謝謝你的幫助! 這就是我現在的解決方案。 – Geya

+0

'[HttpPost] public ActionResult Create(UserViewModel userViewModel) var user = new User(); var newUser = Mapper.Map(userViewModel,user); _repository.Insert(newUser); _repository.Save(); return View(userViewModel); }' – Geya

+0

@Geya如果成功,請選擇此答案爲已接受。 –

0

,你可以這樣做:

[HttpPost] 
    public ActionResult Create(UserViewModel userViewModel) 
    { 
     var user = Mapper.Map<User>(userViewModel); 
     _reoisitory.Add(user); 
    }