2017-08-02 8 views
0

automapperやvalueinjecterのように、mvc asp.netのモデルをviewmodelにマップする方法は数多くあります。しかし、私は戻ってマップする方法を理解することはできません。簡単な例ViewModelをModel(MVC EF)に戻す方法

私はここに

public class Address 
{ 
    public int AddressID { get; set; } 

    public string OwnerID { get; set; } 
    public virtual ApplicationUser Owner { get; set; } 

    public String Name { get; set; } 

    public String Street { get; set; } 

    public int ZipCode { get; set; } 

    public String City { get; set; } 

    public string Email { get; set; } 

    // fancy business logic stuff like 
    public Nullable<Guid> requestCode { get; set; } 

    // or even this 
    public string BestFriendID { get; set; } 
    public virtual ApplicationUser BestFriend{ get; set; } 

    public virtual ICollection<OtherModel> Mycollection { get; set; } 

    // And some enums 
    public MyEnum MyEnum { get; set; } 
} 

このような複雑モデルを持っている。しかし、その後1つのシナリオでは、私はちょうど編集名前と、このアドレスのメールにしたいので、私は行きますそれは

public class SimpleEmailEditVM 
{ 
     [MyDataAnnotations] 
     public String Name { get; set; } 

     [MyDataAnnotations] 
     public String Email { get; set; } 
} 

これは非常に単純なビューのはこの1つ

のように作成することを可能にするために先にとのviewmodelを作成
@model project.ViewModels.SimpleEmailEditVM 
@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" } }) 

であり、ビューモデルに追加することができます。 Streetをフィールドとして使用し、ビューを更新する必要はありません。モデルからビューモデルへのマッピングは、例えば、 valueinjecter、しかし今私の質問:どのように私は戻ってマップするのですか?

ID情報がないので、どのようにして正しいモデルを見つけることができますか?(同じ名前と電子メールを持っていてもIDは全く異なる複数のエントリがあります)コントローラーはどのように見えますか?私は考えることができる

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit([Bind] SimpleEmailEditVM vm) 
    { 
     if (ModelState.IsValid) 
     { 
      /* find the correct address from db and update the 
       fields specified in the viewmodel? */ 
      db.Entry(address).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(address); 
    } 

一つの解決策は、(like this here)IDを付加し、それが隠されて作っています。これは正しいと唯一の方法ですか?ここで問題となっているのは、私のIDが渡されたということです。私は、内部IDのをユーザーに渡すことはあまり良い方法ではないと思います。

答えて

0

temproray session(TempData)を使用して、別のアクションから値をアクションに送信できます。

enter link description here

+0

ビューアクションTempData ["TempId"] = id;ポストアクションで使用するための var id = TempData ["TempId"]; – pisi1001

1

を確認してください、私はこれが ユーザーに内部idを渡すために非常に良い方法ではありません想像することができます。

idを公開することは、idがSSNのような機密データでない限り、それ自体問題ではありません。この質問のIDはURLに公開されています。あなたのユーザーIDはあなたのプロフィールに公開されています。

トリックは、IDが戻ったときにその有効性をチェックし、アクションを実行しているIDがそのアクションを実行できることを確認することです。これはロールまたはアクセス許可のチェックでも、レコードレベルでの細分化が必要な場合もあります。

これを示すいくつかの擬似コードがあります。

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit([Bind] SimpleEmailEditVM vm) 
{ 
    var itemToEdit = db.Find(vm.Id); 

    //Make sure Id is valid 
    if(itemToEdit == null) return BadRequest(); 

    //Make sure user can edit this object 
    if(!User.IsInRole("CanEditItems")) return Forbidden(); 
    if(itemToEdit.AllowedUser != User.Identity.Name) return Forbidden(); 

    if (ModelState.IsValid) 
    { 
     /* find the correct address from db and update the 
      fields specified in the viewmodel? */ 
     db.Entry(address).State = EntityState.Modified; 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(address); 
} 
関連する問題