2012-02-14 47 views
0

我有用戶使用隨IDE提供的AspNetSqlProfileProvider在我的網站某處填寫他們的個人資料信息。如何在使用@ Html.EditorForModel()構建表單時自動填充特定字段?

我允許我的用戶隨時編輯他們的個人資料,方法是轉到編輯個人資料的表單自動填充的編輯個人資料頁面。我目前使用ViewBag用戶的配置文件的每個部件,從我的控制器發送到視圖(地址和城市爲例)做到這一點:

控制器獲得:

ViewBag.address = CustomProfile.GetUserProfile(User.Identity.Name).Address; 
ViewBag.city = CustomProfile.GetUserProfile(User.Identity.Name).City; 

查看:

<div class="editor-field"> 
     @Html.TextBox("Address", (string)ViewBag.address) 
    </div> 

    <div class="editor-field"> 
     @Html.TextBox("City", (string)ViewBag.city) 
    </div> 

控制器後:

public ActionResult ChangeProfile(FormCollection favorites) 
    { 
     CustomProfile profile = CustomProfile.GetUserProfile(); 
     profile.Address = favorites["Address"]; 
     profile.City = favorites["City"]; 
     profile.Save(); 
     return RedirectToAction("Profile"); 
    } 

以上工作正常進行編輯的配置文件,從我的用戶角度來看,它非常流暢(儘管從在線閱讀問題/答案看來,我應該使用ViewModel,並不完全確定如何進行轉換 - 一直失敗)。

當我的用戶從網站(他們一直在購物)去'checkout'時,他們會看到一個屏幕,允許他們輸入最終信息,以便他們購買。我們稱之爲「訂單頁面」。這些詳細信息包括姓名,地址,信用卡信息等。其中一些信息與網站簡介頁面中的信息相同。

我希望能夠自動填充此訂單頁面(名稱,地址)中的某些詳細信息,同時將一些字段留空(信用卡 - 因此用戶必須在每次訪問時填寫這些詳細信息訂單頁面)。

訂單頁面的工作方式與MVC Store Tutorial describes一樣。當顯示訂單頁會顯示使用形式:

@Html.EditorForModel() 

這是偉大的,並允許你編輯的訂貨型號中指定的細節,將允許數據驗證的東西(需要名稱,需要地址,信用卡必須是數字,電子郵件格式正確等),但我無法弄清楚如何使用用戶個人資料中的詳細信息填充此訂單頁面中的特定字段。

我試圖建立一個新的ViewModel,只使用我的個人資料中包含的信息,但我沒有清楚地瞭解需要什麼,因爲我沒有得到我期望的最終結果。

我已經考慮只使用訂單模型作爲我的個人資料信息,但這還不夠,因爲我想要在這兩種信息中提供不同的信息。

我已經考慮使用配置文件信息作爲訂購模型,但我希望我的用戶能夠靈活地存儲配置文件信息,以便與實際下訂單時使用的任何信息分開。

我想我需要知道的具體解決我的問題是如何在使用「@ Html.EditorForModel()」時自動填充特定字段?

對我的整體情況的任何其他幫助都很好,我對任何可以簡化我的流程的建議都很開放(感覺就像我在自己身上做得比我需要的更加困難,而且我處於一個點那裏的合作會讓人覺得呼吸新鮮空氣)。

回答

3

我只能關注問題的前半部分。這是你展示了一些代碼和我可以幫助你的代碼。下半場對我來說完全是一片霧。

所以,當你想設計一個視圖,想想這個視圖需要顯示/編輯的字段。設計視圖模型吧:

public class ChangeProfileViewModel 
{ 
    [Required] 
    public string Address { get; set; } 

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

,然後有一個應該呈現這種觀點填充視圖模型的GET控制器操作:

public ActionResult ChangeProfile() 
{ 
    CustomProfile profile = CustomProfile.GetUserProfile(User.Identity.Name); 
    ChangeProfileViewModel model = new ChangeProfileViewModel 
    { 
     Address = profile.Address, 
     City = profile.City 
    }; 
    return View(model); 
} 

那麼你設計了相應的看法,這將是強類型此視圖模型:

@model ChangeProfileViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.EditorForModel() 
    <button type="submit">OK</button> 
} 

最後你有一個POST控制器動作,將處理提交此表:

[HttpPost] 
public ActionResult ChangeProfile(ChangeProfileViewModel model) 
{ 
    if (!Model.IsValid) 
    { 
     // there were validation errors => redisplay the view 
     return View(model); 
    } 

    // validation succeeded => process the results 
    CustomProfile profile = CustomProfile.GetUserProfile(); 
    profile.Address = model.Address; 
    profile.City = model.City; 
    profile.Save(); 
    return RedirectToAction("Profile"); 
} 

現在,我們在這裏看到的是,在我們的GET和POST行爲都我們有我們的領域模型(CustomProfile)和我們的視圖模型(ChangeProfileViewModel)之間重複的映射代碼。要解決這個問題,我可能會建議你使用AutoMapper。它可以簡化您的GET動作:

public ActionResult ChangeProfile() 
{ 
    CustomProfile profile = CustomProfile.GetUserProfile(User.Identity.Name); 
    ChangeProfileViewModel model = Mapper.Map<CustomProfile, ChangeProfileViewModel>(profile); 
    return View(model); 
} 

或自定義操作過濾器,甚至:

[AutoMap(typeof(CustomProfile), typeof(ChangeProfileViewModel))] 
public ActionResult ChangeProfile() 
{ 
    CustomProfile profile = CustomProfile.GetUserProfile(User.Identity.Name); 
    return View(profile); 
} 

和信件行動:

[HttpPost] 
public ActionResult ChangeProfile(ChangeProfileViewModel model) 
{ 
    if (!Model.IsValid) 
    { 
     // there were validation errors => redisplay the view 
     return View(model); 
    } 

    // validation succeeded => process the results 
    CustomProfile profile = CustomProfile.GetUserProfile(); 
    Mapper.Map<ChangeProfileViewModel, CustomProfile>(model, profile); 
    profile.Save(); 
    return RedirectToAction("Profile"); 
} 

瞭解視圖什麼是重要的模型是你應該總是爲每個視圖使用它們並以這種方式設計它們,以便它們只包含該視圖需要處理的特定信息。留給映射層處理您的域實體和視圖模型之間的轉換。

+0

感謝您的快速回復。我在這個時候睡覺,所以我不得不在早晨嘗試一下,但是看起來你已經給了我一個更全面的ViewModels視圖。 就我原來的文章中缺乏理解而言,我在兩個會話中寫了一個(之後我收到一個冗長的電話),這可能是通過我的格羅夫,我可能會修改。 當我有更多時間專注於您提供給我的內容時,我會進行更新。 – Ecnalyr 2012-02-15 00:58:46

+0

我能夠正確地自動填充我的字段。謝謝。但是,我無法使AutoMapper在我的兩個模型之間進行映射(拋出了一個「異常」)。當我返回到項目的這部分來完善事情時,我可能會進一步討論這個問題。再一次感謝你。 – Ecnalyr 2012-02-15 14:06:33