Asp.net MVC 示例项目Suteki.Shop分析之---ViewData
生活随笔
收集整理的這篇文章主要介紹了
Asp.net MVC 示例项目Suteki.Shop分析之---ViewData
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?????? ?使用強類型的ViewData好處有許多,比如說在IDE中就會有更好的支持,比如代碼提示。同時在View與Controller之間有更嚴謹的“約定”。在Suteki.Shop項目中作者對強類型的ViewPage引入是通過MvcContrib實現的,下面就是其ViewPage<T>代碼(Suteki.Shop\Views\ViewPage.cs):????? ? public?class?ViewPage<T>?:?MvcContrib.FluentHtml.ModelViewPage<T>?where?T?:?class?
{
????????public?ViewPage()?:?base(new?LowercaseFirstCharacterOfNameBehaviour())
????????{}
}
public?class?ViewUserControl<T>?:?MvcContrib.FluentHtml.ModelViewUserControl<T>?where?T?:?class
{
????????public?ViewUserControl()?:?base(new?LowercaseFirstCharacterOfNameBehaviour())
????????{}
}
??????? ?可以看出ViewPage和ViewUserControl只是對MvcContrib中ModelViewPage,ModelViewUserControl的繼承,代碼很簡單,沒什么太多可說的。 ?????? ?強類型的ViewData使用形如:ViewPage<TViewData>,我們可以通過打開一個View看一下,比如“編輯用戶信息”時的視圖頭聲明部分:
?????? <%@?Page?Title=""?Language="C#"??Inherits="Suteki.Shop.ViewPage<ShopViewData>"
?????????其中的ShopViewData就是TViewData。在Suteki.Shop中作者使用ShopViewData對Model中大部分類作了相應的屬性和數據綁定的統一封裝,感覺ShopViewData就是Model的集合體或者是“縮影”,這樣的好處就我看來主要是在View中進行強類型ViewData綁定時統一參數,這里感覺有偷懶之嫌。不過因此造成其自身視圖數據的“庸腫”,其內部有太多的屬性,還是就是綁定傳遞時的效率可能也會存在一些問題(只是猜測,未測試過,呵呵)。 ???????? 好了,下面就開始正文。
???
???????? 首先我們要看一下Suteki.Common\ViewData文件夾下面的幾個類,包括:
????
??????? ?IErrorViewData,IMessageViewData,ViewDataBase等,其類圖如下:
????
????????
????
??????? ?從圖中看出,ViewDataBase是其體系“核心”, 其實現了 IMessageViewData, IErrorViewData這兩個接口。其實體代碼如下:??? ? public?abstract?class?ViewDataBase?:?IMessageViewData,?IErrorViewData
{
????????public?string?Message?{?get;?set;?}
????????public?string?ErrorMessage?{?get;?set;?}
????????public?ViewDataBase?WithErrorMessage(string?errorMessage)
????????{
????????????this.ErrorMessage?=?errorMessage;
????????????return?this;
????????}
????????public?ViewDataBase?WithMessage(string?message)
????????{
????????????this.Message?=?message;
????????????return?this;
????????}
} ??? ??????? ?該抽象類的屬性Message,ErrorMessage分別實現了IMessageViewData和IErrorViewData的接口屬性。主要?用于顯示臨時操作信息(比如“成功添加用戶”,“成功編輯用戶”等)。其所提供的兩個方法“WithErrorMessage”?和“WithMessage”只是對相應屬性的簡單綁定而已。
??
??????? 有了ViewDataBase之后,下面就來看一下其子類實現了,下面是相應類圖:
????
????
?????? ?正如前面所介紹的那樣,子類中最“重要”的當屬“ShopViewData”,其包括了基本所有Model中的類型,并將它們以“屬性”的方法提供出來以便于前臺View使用,同時ShopViewData還提供了與其屬性相關的綁定方法(均以“With...”開頭),下面就是其代碼。??? ? Code
public?class?ShopViewData?:?ViewDataBase
{
????????public?Category?Category?{?get;?set;?}
????????public?IEnumerable<Category>?Categories?{?get;?set;?}
????????public?Product?Product?{?get;?set;?}
????????public?IEnumerable<Product>?Products?{?get;?set;?}
????????public?IEnumerable<Role>?Roles?{?get;?set;?}
????????public?User?User?{?get;?set;?}
????????public?IEnumerable<User>?Users?{?get;?set;?}
????????public?Basket?Basket?{?get;?set;?}
????????public?Order?Order?{?get;?set;?}
????????public?PagedList<Order>?Orders?{?get;?set;?}
????????public?OrderSearchCriteria?OrderSearchCriteria?{?get;?set;?}
????????public?IEnumerable<Country>?Countries?{?get;?set;?}
????????public?Country?Country?{?get;?set;?}
????????public?IEnumerable<CardType>?CardTypes?{?get;?set;?}
????????public?Postage?Postage?{?get;?set;?}
????????public?IEnumerable<Postage>?Postages?{?get;?set;?}
????????public?PostageResult?PostageResult?{?get;?set;?}
????????public?Card?Card?{?get;?set;?}
????????public?IEnumerable<StockItem>?StockItems?{?get;?set;?}
????????public?IEnumerable<Content>?Contents?{?get;?set;?}
????????public?IEnumerable<OrderStatus>?OrderStatuses?{?get;?set;?}
????????//?attempt?at?a?fluent?interface
????????public?ShopViewData?WithCategory(Category?category)
????????{
????????????this.Category?=?category;
????????????return?this;
????????}
????????public?ShopViewData?WithCategories(IEnumerable<Category>?categories)
????????{
????????????this.Categories?=?categories;
????????????return?this;
????????}
????????public?ShopViewData?WithProduct(Product?product)
????????{
????????????this.Product?=?product;
????????????return?this;
????????}
????????public?ShopViewData?WithProducts(IEnumerable<Product>?products)
????????{
????????????this.Products?=?products;
????????????return?this;
????????}
????????public?ShopViewData?WithRoles(IEnumerable<Role>?roles)
????????{
????????????this.Roles?=?roles;
????????????return?this;
????????}
????????public?ShopViewData?WithUser(User?user)
????????{
????????????this.User?=?user;
????????????return?this;
????????}
????????public?ShopViewData?WithUsers(IEnumerable<User>?users)
????????{
????????????this.Users?=?users;
????????????return?this;
????????}
????????public?ShopViewData?WithBasket(Basket?basket)
????????{
????????????this.Basket?=?basket;
????????????return?this;
????????}
????????public?ShopViewData?WithOrders(PagedList<Order>?orders)
????????{
????????????this.Orders?=?orders;
????????????return?this;
????????}
????????public?ShopViewData?WithOrder(Order?order)
????????{
????????????this.Order?=?order;
????????????return?this;
????????}
????????public?ShopViewData?WithOrderSearchCriteria(OrderSearchCriteria?orderSearchCriteria)
????????{
????????????this.OrderSearchCriteria?=?orderSearchCriteria;
????????????return?this;
????????}
????????public?ShopViewData?WithCountries(IEnumerable<Country>?countries)
????????{
????????????this.Countries?=?countries;
????????????return?this;
????????}
????????public?ShopViewData?WithCountry(Country?country)
????????{
????????????this.Country?=?country;
????????????return?this;
????????}
????????public?ShopViewData?WithCardTypes(IEnumerable<CardType>?cardTypes)
????????{
????????????this.CardTypes?=?cardTypes;
????????????return?this;
????????}
????????public?ShopViewData?WithPostage(Postage?postage)
????????{
????????????this.Postage?=?postage;
????????????return?this;
????????}
????????public?ShopViewData?WithPostages(IEnumerable<Postage>?postages)
????????{
????????????this.Postages?=?postages;
????????????return?this;
????????}
????????public?ShopViewData?WithTotalPostage(PostageResult?postageResult)
????????{
????????????this.PostageResult?=?postageResult;
????????????return?this;
????????}
????????public?ShopViewData?WithCard(Card?card)
????????{
????????????this.Card?=?card;
????????????return?this;
????????}
????????public?ShopViewData?WithStockItems(IEnumerable<StockItem>?stockItems)
????????{
????????????this.StockItems?=?stockItems;
????????????return?this;
????????}
????????public?ShopViewData?WithContents(IEnumerable<Content>?contents)
????????{
????????????this.Contents?=?contents;
????????????return?this;
????????}
????????public?ShopViewData?WithOrderStatuses(IEnumerable<OrderStatus>?orderStatuses)
????????{
????????????this.OrderStatuses?=?orderStatuses;
????????????return?this;
????????}
} ????
???????? 為了便于使用,Suteki.Shop還以靜態屬性的方式進行了封閉,最終以ShopView這個類開放出來提供給Action和View使用,其實現代碼如下:???? ? ///?<summary>
///?So?you?can?write?
///?ShopView.Data.WithProducts(myProducts);
///?</summary>
public?class?ShopView
{
?????public?static?ShopViewData?Data?{?get?{?return?new?ShopViewData();?}?}
}
?????? ? 下面以“編輯用戶”這個Action來看一下其使用方法:? [AcceptVerbs(HttpVerbs.Post),?UnitOfWork]
public?ActionResult?Edit([DataBind]?User?user,?string?password)
{
????????if(!?string.IsNullOrEmpty(password))
????????{
????????????user.Password?=?userService.HashPassword(password);
????????}
????????try
????????{
????????????user.Validate();
????????}
????????catch?(ValidationException?validationException)
????????{
????????????validationException.CopyToModelState(ModelState,?"user");
????????????return?View("Edit",?EditViewData.WithUser(user));
????????}
????????return?View("Edit",?EditViewData.WithUser(user).WithMessage("Changes?have?been?saved"));?
} ??? ??????? ?注意其中的EditViewData屬性就是初始化一個ShopViewData實例并調用該實例的WithRoles()方法來完成對用戶規則的獲取。然后在"Edit"這個Action的返回語句中繼續綁定其他信息,如當前編輯的用戶信息“user”,以及操作提示信息“Changes have been saved”。 ?????? ? 這樣就可以在View中對ShopViewData進行顯示操作了。這里要說明的是在View中對Message的顯示是通過下面這一行完成的:????? ? <%=?Html.MessageBox(ViewData.Model)?%>
???????? 而這個方法是對HtmlHelper這個MVC類的擴展方法,其方法定義如下:?? public?static?string?MessageBox(this?HtmlHelper?htmlHelper,?IMessageViewData?messageViewData)
{
????if?(messageViewData.Message?==?null)?return?string.Empty;
????HtmlTextWriter?writer?=?new?HtmlTextWriter(new?StringWriter());
????writer.AddAttribute("class",?"message");
????writer.RenderBeginTag(HtmlTextWriterTag.Div);
????writer.Write(messageViewData.Message);
????writer.RenderEndTag();
????return?writer.InnerWriter.ToString();
}
??????? ? 大家看到了其傳入的參數是IMessageViewData類型,而傳入的是“ShopViewData”類型,如下圖所示:
?????? ??????? 而看過上面內容的話,就可以通過其類圖中實現的方法看出這個繼承實現鏈表:? ??????ShopViewData?==>?ViewDataBase?==?>?IMessageViewData
????
???????? 所以擴展文法直接就完成了這種“向上轉型”操作。????
????
?????? ??除了“編輯用戶”這種在Action中直接綁定Message字段屬性的方式,Suteki.Shop還提供了Filter方式的“操作信息”綁定,比如CopyMessageFromTempDataToViewData(Suteki.Shop\Filters),其代碼如下: ? public?class?CopyMessageFromTempDataToViewData?:?ActionFilterAttribute
{
????????public?override?void?OnActionExecuted(ActionExecutedContext?filterContext)?
????????{
????????????????var?result?=?filterContext.Result?as?ViewResult;
????????????????if(result?!=?null?&&?filterContext.Controller.TempData.ContainsKey("message"))
????????????????{
????????????????????var?model?=?result.ViewData.Model?as?ShopViewData;
????????????????????if(model?!=?null?&&?string.IsNullOrEmpty(model.Message))
????????????????????{
????????????????????????model.Message?=?filterContext.Controller.TempData["message"]?as?string;
????????????????????}
????????????????}
????????}
}
????
????
??? ???? 大家請注意,上面的filterContext.Controller類型是ControllerBase(詳細說明參見我之前寫的這篇文章),其提供了Message屬性來實現臨時數據TempData["message"]的獲取來綁定工作,代碼如下: [Rescue("Default"),?Authenticate,?CopyMessageFromTempDataToViewData]
public?abstract?class?ControllerBase?:?Controller,?IProvidesBaseService
{
????????
????????
?????public?string?Message
?????{
?????????get?{?return?TempData["message"]?as?string;?}
?????????set?{?TempData["message"]?=?value;?}
?????}
}
????
???????? 這樣就可以通過CopyMessageFromTempDataToViewData這個Filter來實現將臨時數據綁定到ShopViewData中的Message屬性,并提供給前臺View使用了。當然這是有條件的,就是上面代碼中的這一行:
????if(model?!=?null?&&?string.IsNullOrEmpty(model.Message))?
???????? 從邏輯上看,這樣做應該是防止對已綁定操作信息(model.Message不為空)進行“誤覆蓋”吧。
???
???
?????? ? 好了,今天的內容就先到這里了。
????
??????
????
????
???
????
????
????
???
{
????????public?ViewPage()?:?base(new?LowercaseFirstCharacterOfNameBehaviour())
????????{}
}
public?class?ViewUserControl<T>?:?MvcContrib.FluentHtml.ModelViewUserControl<T>?where?T?:?class
{
????????public?ViewUserControl()?:?base(new?LowercaseFirstCharacterOfNameBehaviour())
????????{}
}
??????? ?可以看出ViewPage和ViewUserControl只是對MvcContrib中ModelViewPage,ModelViewUserControl的繼承,代碼很簡單,沒什么太多可說的。 ?????? ?強類型的ViewData使用形如:ViewPage<TViewData>,我們可以通過打開一個View看一下,比如“編輯用戶信息”時的視圖頭聲明部分:
?????? <%@?Page?Title=""?Language="C#"??Inherits="Suteki.Shop.ViewPage<ShopViewData>"
?????????其中的ShopViewData就是TViewData。在Suteki.Shop中作者使用ShopViewData對Model中大部分類作了相應的屬性和數據綁定的統一封裝,感覺ShopViewData就是Model的集合體或者是“縮影”,這樣的好處就我看來主要是在View中進行強類型ViewData綁定時統一參數,這里感覺有偷懶之嫌。不過因此造成其自身視圖數據的“庸腫”,其內部有太多的屬性,還是就是綁定傳遞時的效率可能也會存在一些問題(只是猜測,未測試過,呵呵)。 ???????? 好了,下面就開始正文。
???
???????? 首先我們要看一下Suteki.Common\ViewData文件夾下面的幾個類,包括:
????
??????? ?IErrorViewData,IMessageViewData,ViewDataBase等,其類圖如下:
????
????????
????
??????? ?從圖中看出,ViewDataBase是其體系“核心”, 其實現了 IMessageViewData, IErrorViewData這兩個接口。其實體代碼如下:??? ? public?abstract?class?ViewDataBase?:?IMessageViewData,?IErrorViewData
{
????????public?string?Message?{?get;?set;?}
????????public?string?ErrorMessage?{?get;?set;?}
????????public?ViewDataBase?WithErrorMessage(string?errorMessage)
????????{
????????????this.ErrorMessage?=?errorMessage;
????????????return?this;
????????}
????????public?ViewDataBase?WithMessage(string?message)
????????{
????????????this.Message?=?message;
????????????return?this;
????????}
} ??? ??????? ?該抽象類的屬性Message,ErrorMessage分別實現了IMessageViewData和IErrorViewData的接口屬性。主要?用于顯示臨時操作信息(比如“成功添加用戶”,“成功編輯用戶”等)。其所提供的兩個方法“WithErrorMessage”?和“WithMessage”只是對相應屬性的簡單綁定而已。
??
??????? 有了ViewDataBase之后,下面就來看一下其子類實現了,下面是相應類圖:
????
????
?????? ?正如前面所介紹的那樣,子類中最“重要”的當屬“ShopViewData”,其包括了基本所有Model中的類型,并將它們以“屬性”的方法提供出來以便于前臺View使用,同時ShopViewData還提供了與其屬性相關的綁定方法(均以“With...”開頭),下面就是其代碼。??? ? Code
public?class?ShopViewData?:?ViewDataBase
{
????????public?Category?Category?{?get;?set;?}
????????public?IEnumerable<Category>?Categories?{?get;?set;?}
????????public?Product?Product?{?get;?set;?}
????????public?IEnumerable<Product>?Products?{?get;?set;?}
????????public?IEnumerable<Role>?Roles?{?get;?set;?}
????????public?User?User?{?get;?set;?}
????????public?IEnumerable<User>?Users?{?get;?set;?}
????????public?Basket?Basket?{?get;?set;?}
????????public?Order?Order?{?get;?set;?}
????????public?PagedList<Order>?Orders?{?get;?set;?}
????????public?OrderSearchCriteria?OrderSearchCriteria?{?get;?set;?}
????????public?IEnumerable<Country>?Countries?{?get;?set;?}
????????public?Country?Country?{?get;?set;?}
????????public?IEnumerable<CardType>?CardTypes?{?get;?set;?}
????????public?Postage?Postage?{?get;?set;?}
????????public?IEnumerable<Postage>?Postages?{?get;?set;?}
????????public?PostageResult?PostageResult?{?get;?set;?}
????????public?Card?Card?{?get;?set;?}
????????public?IEnumerable<StockItem>?StockItems?{?get;?set;?}
????????public?IEnumerable<Content>?Contents?{?get;?set;?}
????????public?IEnumerable<OrderStatus>?OrderStatuses?{?get;?set;?}
????????//?attempt?at?a?fluent?interface
????????public?ShopViewData?WithCategory(Category?category)
????????{
????????????this.Category?=?category;
????????????return?this;
????????}
????????public?ShopViewData?WithCategories(IEnumerable<Category>?categories)
????????{
????????????this.Categories?=?categories;
????????????return?this;
????????}
????????public?ShopViewData?WithProduct(Product?product)
????????{
????????????this.Product?=?product;
????????????return?this;
????????}
????????public?ShopViewData?WithProducts(IEnumerable<Product>?products)
????????{
????????????this.Products?=?products;
????????????return?this;
????????}
????????public?ShopViewData?WithRoles(IEnumerable<Role>?roles)
????????{
????????????this.Roles?=?roles;
????????????return?this;
????????}
????????public?ShopViewData?WithUser(User?user)
????????{
????????????this.User?=?user;
????????????return?this;
????????}
????????public?ShopViewData?WithUsers(IEnumerable<User>?users)
????????{
????????????this.Users?=?users;
????????????return?this;
????????}
????????public?ShopViewData?WithBasket(Basket?basket)
????????{
????????????this.Basket?=?basket;
????????????return?this;
????????}
????????public?ShopViewData?WithOrders(PagedList<Order>?orders)
????????{
????????????this.Orders?=?orders;
????????????return?this;
????????}
????????public?ShopViewData?WithOrder(Order?order)
????????{
????????????this.Order?=?order;
????????????return?this;
????????}
????????public?ShopViewData?WithOrderSearchCriteria(OrderSearchCriteria?orderSearchCriteria)
????????{
????????????this.OrderSearchCriteria?=?orderSearchCriteria;
????????????return?this;
????????}
????????public?ShopViewData?WithCountries(IEnumerable<Country>?countries)
????????{
????????????this.Countries?=?countries;
????????????return?this;
????????}
????????public?ShopViewData?WithCountry(Country?country)
????????{
????????????this.Country?=?country;
????????????return?this;
????????}
????????public?ShopViewData?WithCardTypes(IEnumerable<CardType>?cardTypes)
????????{
????????????this.CardTypes?=?cardTypes;
????????????return?this;
????????}
????????public?ShopViewData?WithPostage(Postage?postage)
????????{
????????????this.Postage?=?postage;
????????????return?this;
????????}
????????public?ShopViewData?WithPostages(IEnumerable<Postage>?postages)
????????{
????????????this.Postages?=?postages;
????????????return?this;
????????}
????????public?ShopViewData?WithTotalPostage(PostageResult?postageResult)
????????{
????????????this.PostageResult?=?postageResult;
????????????return?this;
????????}
????????public?ShopViewData?WithCard(Card?card)
????????{
????????????this.Card?=?card;
????????????return?this;
????????}
????????public?ShopViewData?WithStockItems(IEnumerable<StockItem>?stockItems)
????????{
????????????this.StockItems?=?stockItems;
????????????return?this;
????????}
????????public?ShopViewData?WithContents(IEnumerable<Content>?contents)
????????{
????????????this.Contents?=?contents;
????????????return?this;
????????}
????????public?ShopViewData?WithOrderStatuses(IEnumerable<OrderStatus>?orderStatuses)
????????{
????????????this.OrderStatuses?=?orderStatuses;
????????????return?this;
????????}
} ????
???????? 為了便于使用,Suteki.Shop還以靜態屬性的方式進行了封閉,最終以ShopView這個類開放出來提供給Action和View使用,其實現代碼如下:???? ? ///?<summary>
///?So?you?can?write?
///?ShopView.Data.WithProducts(myProducts);
///?</summary>
public?class?ShopView
{
?????public?static?ShopViewData?Data?{?get?{?return?new?ShopViewData();?}?}
}
?????? ? 下面以“編輯用戶”這個Action來看一下其使用方法:? [AcceptVerbs(HttpVerbs.Post),?UnitOfWork]
public?ActionResult?Edit([DataBind]?User?user,?string?password)
{
????????if(!?string.IsNullOrEmpty(password))
????????{
????????????user.Password?=?userService.HashPassword(password);
????????}
????????try
????????{
????????????user.Validate();
????????}
????????catch?(ValidationException?validationException)
????????{
????????????validationException.CopyToModelState(ModelState,?"user");
????????????return?View("Edit",?EditViewData.WithUser(user));
????????}
????????return?View("Edit",?EditViewData.WithUser(user).WithMessage("Changes?have?been?saved"));?
} ??? ??????? ?注意其中的EditViewData屬性就是初始化一個ShopViewData實例并調用該實例的WithRoles()方法來完成對用戶規則的獲取。然后在"Edit"這個Action的返回語句中繼續綁定其他信息,如當前編輯的用戶信息“user”,以及操作提示信息“Changes have been saved”。 ?????? ? 這樣就可以在View中對ShopViewData進行顯示操作了。這里要說明的是在View中對Message的顯示是通過下面這一行完成的:????? ? <%=?Html.MessageBox(ViewData.Model)?%>
???????? 而這個方法是對HtmlHelper這個MVC類的擴展方法,其方法定義如下:?? public?static?string?MessageBox(this?HtmlHelper?htmlHelper,?IMessageViewData?messageViewData)
{
????if?(messageViewData.Message?==?null)?return?string.Empty;
????HtmlTextWriter?writer?=?new?HtmlTextWriter(new?StringWriter());
????writer.AddAttribute("class",?"message");
????writer.RenderBeginTag(HtmlTextWriterTag.Div);
????writer.Write(messageViewData.Message);
????writer.RenderEndTag();
????return?writer.InnerWriter.ToString();
}
??????? ? 大家看到了其傳入的參數是IMessageViewData類型,而傳入的是“ShopViewData”類型,如下圖所示:
?????? ??????? 而看過上面內容的話,就可以通過其類圖中實現的方法看出這個繼承實現鏈表:? ??????ShopViewData?==>?ViewDataBase?==?>?IMessageViewData
????
???????? 所以擴展文法直接就完成了這種“向上轉型”操作。????
????
?????? ??除了“編輯用戶”這種在Action中直接綁定Message字段屬性的方式,Suteki.Shop還提供了Filter方式的“操作信息”綁定,比如CopyMessageFromTempDataToViewData(Suteki.Shop\Filters),其代碼如下: ? public?class?CopyMessageFromTempDataToViewData?:?ActionFilterAttribute
{
????????public?override?void?OnActionExecuted(ActionExecutedContext?filterContext)?
????????{
????????????????var?result?=?filterContext.Result?as?ViewResult;
????????????????if(result?!=?null?&&?filterContext.Controller.TempData.ContainsKey("message"))
????????????????{
????????????????????var?model?=?result.ViewData.Model?as?ShopViewData;
????????????????????if(model?!=?null?&&?string.IsNullOrEmpty(model.Message))
????????????????????{
????????????????????????model.Message?=?filterContext.Controller.TempData["message"]?as?string;
????????????????????}
????????????????}
????????}
}
????
????
??? ???? 大家請注意,上面的filterContext.Controller類型是ControllerBase(詳細說明參見我之前寫的這篇文章),其提供了Message屬性來實現臨時數據TempData["message"]的獲取來綁定工作,代碼如下: [Rescue("Default"),?Authenticate,?CopyMessageFromTempDataToViewData]
public?abstract?class?ControllerBase?:?Controller,?IProvidesBaseService
{
????????
????????
?????public?string?Message
?????{
?????????get?{?return?TempData["message"]?as?string;?}
?????????set?{?TempData["message"]?=?value;?}
?????}
}
????
???????? 這樣就可以通過CopyMessageFromTempDataToViewData這個Filter來實現將臨時數據綁定到ShopViewData中的Message屬性,并提供給前臺View使用了。當然這是有條件的,就是上面代碼中的這一行:
????if(model?!=?null?&&?string.IsNullOrEmpty(model.Message))?
???????? 從邏輯上看,這樣做應該是防止對已綁定操作信息(model.Message不為空)進行“誤覆蓋”吧。
???
???
?????? ? 好了,今天的內容就先到這里了。
????
??????
????
????
???
????
????
????
???
轉載于:https://blog.51cto.com/daizhj/160560
總結
以上是生活随笔為你收集整理的Asp.net MVC 示例项目Suteki.Shop分析之---ViewData的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Q学习(Q-learning)入门小例子
- 下一篇: 海思Hi3798处理器参数,Hi3798