2017-08-06 66 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); 
    }