ASP.NET MVC 實現模式 – ModelBuilder

來源:互聯網
上載者:User
文章目錄
  • 通常的情況
  • 1. 問題
  • 2. 分析
  • 3. 改造

ViewModel的建立過程從Controller中分離到ModelBuilder中,本質上是為了職責的分離,也提高了Controller的可讀性。

通常的情況

使用MVC時,在Controller中,會包含很多用於建立ViewModel的代碼。
讓我們從一個例子開始。
假設我們有一個用於呈現填寫訂單的頁面(~\Order\FT-BJS-95486),對應的Action 如下:

public ActionResult Order(string productNo){    var p = ProductService.GetProduct(productNo);    var model = new OrderModel    {        ProductNo = productNo,        ProductName = p.ProductName,    };    return View(model);}

其中OrderModel 這個ViewModel的定義為:

public class OrderModel {    public string ProductNo { get; set; }    public string ProductName { get; set; }    public int Count { get; set; }    public string Address { get; set; }}

接下來,為了接收使用者輸入的訂單資訊,我們可能會有這樣一個Action

[HttpPost]public ActionResult Order(OrderModel model){    var p = ProductService.GetProduct(productNo);    if(!ModelState.IsVaidate())    {        // 這裡假設:        // 1. ProductName並沒用通過hidden input的方式post回來        // 2. ProductNo 隨同其它使用者輸入資訊post回來        model.ProductName = p.ProductName;        return View(model);    }    var model2 = new OrderConfirmModel    {        ProductNo = model.ProductNo,        ProductName = p.ProductName,        Count = model.Count,        Address = model.Address,    };    return View("OrderConfirm", model2);}
1. 問題
  1. 有些ViewModel的建立可能比較“複雜”,從閱讀Controller的角度,不是“主控制流程”
  2. ViewModel會在不同階段被建立出來,不同階段的建立過程,往往出現一些重複的代碼
2. 分析

在上述的例子中,雖然OrderModel本身的結構及建立過程都非常簡單,但我們依然可以識別出重複的部分:

var p = ProductService.GetProduct(productNo);model.ProductName = product.ProductName;

我們可以歸納出這些重複的部分,分屬於兩個ViewModel被建立的“階段”:

  1. Create
  2. Rebuild

我們據此抽象出IModelBuilder介面

public interface IModelBuilder<TViewModel>{    TViewModel Create();    TViewModel Rebuild(TViewModel model);}
3. 改造

我們來寫一個OrderModelBuilder,實現IModelBuilder介面

public class OrderModelBuilder : IModelBuilder<OrderModel>{    private string _productNo;    private string _productName;    public OrderModelBuilder(string productNo, string productName)    {        _productNo = productNo;        _productName = productName;    }    public OrderModel Create()    {        var model = new OrderModel        {            ProductNo = _productNo,        };        model = this.Rebuild(model);        return model;    }    public OrderModel Rebuild(OrderModel model)    {        model.ProductName = _productName;        return model;    }}

用OrderModelBuilder來簡化OrderController

private OrderModelBuilder GetBuilder(string productNo){    var p = ProductService.GetProduct(productNo);    var builder = new OrderModelBuilder(p);    return builder;}public ActionResult Order(string productNo){    var builder = GetBuilder(productNo);    var model = builder.Create();    return View(model);}[HttpPost]public ActionResult Order(OrderModel model){    if(!model.IsVaidate())    {        var builder = GetBuilder(model.ProductNo);        var model = builder.Rebuild(model);        return View(model);    }    // 根據OrderModel建立OrderConfirmModel    var builder2 = new OrderConfirmModelBuilder(model);    var model2 = builder2.Create();    return View("OrderConfirm", model2);}

這樣,就解決了我們在第1節中提出的兩個問題。

此文介紹的內容,無關語言和平台。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.