2017-08-06 10 views
2

ASP.Net MVCプロジェクトでリポジトリ、ビューモデル、マッピングを使用してCRUD操作を実装する際に問題があります。 「詳細」(1つのオブジェクトに関する情報を読む)と「インデックス」(オブジェクトのリスト全体を読む)は、コントローラが動作しています。リポジトリとマッピングを使用してMVCデザインパターンを実装するC#

ModelViewModelにマッピングしてからViewに表示しています。しかし、CreateUpdateおよびDeleteの操作では、ViewModelModelにマップする必要があります。どこが間違っているのか教えていただけますか?

モデル

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

"私がモデルにViewModelに地図すべきである。" - 正確に - ちょうどそれを行います。あなたが経験している問題は何ですか?通常、DTOがあります。例えば、フォームデータとして入ってくる「UserDto」と言います。 'User'にマップし、新しく作成したインデックスの詳細ページにリダイレクトします。 – ironstone13

+0

いくつかの例やリンクを教えてください。それは私が初めてそれをして、私は迷っています。私はどこに私の問題があるとコメントします。私の作成コントローラでは、// var users = _repository.Insert(user); – Geya

+0

create関数では 'User'の代わりに' UserViewModel'を使い、 'User'に写像してデータベースに保存します。 –

答えて

0
  1. あなたCreateビューであなたのモデルは、あなたの012でありますであり、コントローラに渡す必要があります(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] 公共のActionResult作成(UserViewModel userViewModel) {VARユーザ=新しいユーザー(); var newUser = Mapper.Map(userViewModel、user); _repository.Insert(newUser); _repository.Save(); リターンビュー(userViewModel);それが正常に働いていた場合は受理として } ' – Geya

+0

@Geyaは、この答えを選択してください。 –

0

あなたはこのように行うことができます。

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