Реализация шаблона проектирования MVC с репозиториями и отображением, C#

У меня проблема с реализацией операций CRUD с использованием репозиториев, моделей представлений и отображений в моем проекте ASP.Net MVC. У "деталей"(читайте информацию об одном объекте) и у "индекса"(читайте весь список объектов) контроллеры работают.

Я картирую Model в ViewModel а затем отобразить его в View, Но для Create, Update а также Delete операции, я должен отобразить 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>

3 ответа

Для использования функции создания 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);
}

Вы можете сделать так:

    [HttpPost]
    public ActionResult Create(UserViewModel userViewModel)
    {
        var user = Mapper.Map<User>(userViewModel);
        _reoisitory.Add(user);
    }
  1. Ваша модель в вашем Create взгляд твой UserViewModel и это должно быть передано в контроллер, а не User,

  2. Шаблон, который вы создали, предполагает, что пользователь сначала будет Create просматривать при вводе новой информации пользователя. Таким образом, они перейдут к этому виду, не передавая ему никаких объектов в своей первой поездке. Если это так, вам понадобится конструктор без параметров для первого посещения, когда вы просто создадите новый UserViewModel и передайте его. После создания пользователя вы возвращаетесь к этому представлению, которое представит им форму и будет очень запутанным для пользователя. Возможно, вы захотите перенаправить на страницу подтверждения или страницу входа с сообщением о том, что пользователь создан.

  3. Всякий раз, когда вы вносите изменения в данные, EntityFramework не будет вносить эти изменения, пока вы не вызовете SaveChanges для хранилища. Странно, что вы не сохраняете нового пользователя сразу после его создания.

DbSet.Add

DbContext.SaveChanges

Другие вопросы по тегам