ASP.NET MVC 实现模式 - ModelBuilder

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节中提出的两个问题。

此文介绍的内容,无关语言和平台。

转载于:https://www.cnblogs.com/yicone/archive/2013/03/31/2991339.html

ASP.NET MVC 局部刷新(Partial Refresh)是一个技术特性,允许开发者仅更新页面的一部分而无需完全重新加载整个页面。这可以提升用户体验,并减少服务器负担。以下是实现 ASP.NET MVC 局部刷新的一些步骤: ### 实现步骤 #### 1. 创建模型(Model) 首先,创建一个数据模型(例如 `Product`),并确保它能够在数据库中存储产品信息。 ```csharp public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } ``` #### 2. 数据访问层(Repository 或 DbContext) 通常,你可以使用 `DbContext` 来处理数据库操作,也可以自定义一个 Repository 类来封装所有数据相关的操作。这里我们使用简单的 `DbContext` 示例: ```csharp public partial class AppDbContext : DbContext { public DbSet<Product> Products { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Product>().ToTable("Products"); } } ``` #### 3. 控制器(Controller) 在控制器中创建一个 Action,用于获取数据并将它们传递给视图。例如: ```csharp public ActionResult GetProducts() { var products = _context.Products.ToList(); return PartialView("_ProductList", products); } ``` 这里假设 `_context` 已经引用了 `AppDbContext` 的实例,并且 `_ProductList` 视图已经预先配置好了展示产品的模板。 #### 4. 视图(View) 在视图中,我们可以直接插入 HTML 表单、列表或其他元素。为了实现局部刷新,我们需要利用 AJAX 请求。下面是一个简单的示例: HTML: ```html <div id="product-list"> @{await Html.PartialAsync("_ProductList");} </div> <script type="text/javascript"> function refreshData() { $.ajax({ url: '/Products/GetProducts', success: function(data) { $('#product-list').html(''); await Html.RenderAction("GetProducts", "Home"); }, error: function(error) { console.log('Error:', error); } }); } // 刷新按钮点击事件 document.getElementById("refresh-button").addEventListener("click", refreshData); </script> ``` 这里的 AJAX 调用会请求 `/Products/GetProducts`,成功后将返回的数据清空当前 `#product-list` 区域,并通过 JavaScript 再次渲染视图到该区域。 #### 相关问题 - 扩展与优化 1. **如何在大型项目中管理局部刷新?** 在大型项目中,可能会涉及到多个控制器和视图进行局部刷新。使用异步编程、缓存策略以及版本控制机制可以帮助简化管理和提高性能。 2. **局部刷新与全页刷新的区别是什么?** 全页刷新意味着用户界面的所有部分都会重新加载,包括所有动态内容和静态资源。相比之下,局部刷新只针对特定部分的内容进行更新,减少了网络传输量和服务器压力。 3. **如何确保局部刷新的安全性和性能?** 确保局部刷新安全的方式包括使用 CORS(跨源资源共享)、HTTPS 加密传输、输入验证等。从性能角度考虑,可以采用缓存策略、最小化 HTTP 请求、使用CDN加速等手段来优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值