我找到了一種方法來實現我的ViewData/ViewModel方法,而不用太多的ASP.NET MVC。
我是這樣做的:
這是我ViewPage2
類暴露的強類型的ViewData對象的意見。不幸的是,你需要使用反射來避免ViewPage創建一個全新的ViewDataDictionary的行爲,但是靜態緩存的FieldInfo對象並不比MVC的路由動態控制器/動作查找更昂貴。
public class ViewPage2<TModel,TData> : ViewPage<TModel> where TData : ViewDataDictionary<TModel> {
public ViewPage2() : base() {
}
private Boolean _dataPresent;
private TData _data;
public new TData ViewData {
get {
if(_dataPresent && _data == null) {
_data = (TData)base.ViewData;
}
return _data;
}
}
// Cached in static class state for performance.
private static readonly FieldInfo _viewPage1ViewData;
private static readonly FieldInfo _viewPage2ViewData;
static ViewPage2() {
Type viewPage1 = typeof(ViewPage<TModel>);
_viewPage1ViewData = viewPage1.GetField("_viewData", BindingFlags.Instance | BindingFlags.NonPublic);
Type viewPage2 = typeof(ViewPage);
_viewPage2ViewData = viewPage2.GetField("_viewData", BindingFlags.Instance | BindingFlags.NonPublic);
}
protected override void SetViewData(ViewDataDictionary viewData) {
// ViewPage<TModel> creates a new ViewDataDictionary<TModel> when this method is called, even if viewData is of the correct type.
// The trick is to reimplement SetViewData and set base._viewData and basebase._viewData
if(viewData is TData) {
_viewPage1ViewData.SetValue(this, viewData);
_viewPage2ViewData.SetValue(this, viewData);
_dataPresent = true;
} else {
base.SetViewData(viewData);
}
}
}
然後,每* .aspx文件(我用的是WebFormViewEngine)我只是改變了@Page
指令:
<%@ Page Language="C#" MasterPageFile="~/Site.Master" Inherits="Me.ViewPage2<Me.FormModel,Me.FormData>" %>
我承認這兩個泛型類型說明符讓它有點繁瑣,但這是你只需要設置一次的東西。
然後在每個控制器,它只是一個這樣的事情:
public ActionResult Edit() {
FormData data = new FormData();
data.SomeStronglyTypedField = "foo";
this.ViewData = data;
}
在每個視圖現在可以從強類型的視圖數據中受益:
<p><%= ViewData.SomeStronglyTypedField %></p>
而且因爲ViewData的不是一部分在處理POST提交的數據和自動綁定的好處時存在關注的分離:
[HttpPost]
public ActionResult Edit(EditModel model) {
if(!ModelState.IsValid) {
// See how I can return the model object without modifying it. All I need to do is re-create the View data.
FormData data = new FormData();
data.SomeStronglyTypedField = "foo";
this.ViewData = data;
return View(model);
}
// persist to DB here
return RedirectToAction("View");
}
實際上,我使用一個通用的BaseController類來處理ViewData對象的自動創建和設置,因此我不需要在每個操作中使用這三行(FormData data...
等)。
來源
2012-07-09 16:29:35
Dai
一種方法是:單個視圖模型可以具有稱爲ViewObjects(屬性集合)的屬性,以在主視圖中填充只讀部分。 – 2012-07-07 04:03:49