ASP.NET MVC - 为分层视图获取正确的默认数据绑定
序幕
开发人员在处理HttpPost操作时通常会遇到默认绑定问题。例如:如果您已将视图、视图模型、控制器操作和数据全部连接起来,并且您的表单看起来应该可以正常工作,但是当您按下“保存”按钮后,模型到达控制器时,模型为空或部分为空,则您可能需要对视图进行一些调整,以使 Razor 引擎正确编写 HTML。正确获取客户端代码至关重要,如果代码错误,则会默默失败。
如果您只是需要这方面的帮助,请跳至“保存数据”部分。
如果您认为更完整的案例研究会对您有益,请继续阅读。
介绍
许多开发人员都知道,他们可以使用 ASP.NET 模型绑定以最少的代码在网页上创建表单。Visual Studio 的默认 MVC 视图模板甚至可以创建标准列表,创建、编辑和删除视图,而无需任何额外的编程。
但是默认模型绑定的功能不仅限于简单的输入表单或记录列表的平面数据模型。使用一些简单的编码技术,开发人员可以使用 ASP.NET 创建表单并收集分层实体关系的数据。在许多应用程序中,这可以决定是利用 ASP.NET MVC 的快速开发功能,还是依赖 Angular 或 React 等客户端框架的额外基础架构和复杂性。
本指南将提供使用 ASP.NET MVC 模型绑定以分层结构呈现和收集分层表单数据的示例。
技能水平
以指示的技能水平理解这些主题将会有所帮助:
技术 | 技能水平 |
---|---|
网上邻居 | 中间的 |
C# | 中间的 |
实体框架 | 初学者 |
MVC | 中间的 |
MVVM | 初学者 |
范围
本指南将提供使用 ASP.NET MVC 模型绑定以分层结构呈现和收集分层表单数据的示例。
本指南中提供的示例项目和代码基于 .NET Framework。.NET Core 和 .NET Standard 的实现细节将在另一本指南中介绍。
结构
我们将首先概述案例研究实体和用于准备本指南的示例解决方案的主要视图。
然后,我们将看到如何创建一个视图模型,该模型包含各种原始类型的成员字段,并包含一个对象类型集合的字段。
接下来,我们将研究向最终用户呈现信息所需的代码。
我们将仔细研究如何确保 Razor 代码创建正确的 HTML,并了解如何使用 HtmlHelpers 和 CSS 将格式应用于视图创建的表单字段。
案例研究
本指南中显示的代码和屏幕截图与示例 Visual Studio 项目的代码和视图布局相匹配。 可以从 GitHub 存储库分叉或下载该解决方案:
github.com/ajsaulsberry/BlipBinding
示例解决方案实现了以下内容:
- 具有独立项目的多项目解决方案
- Web 应用程序
- 实体
- 数据层(上下文和存储库)
- 模型视图 ViewModel (MVVM) 设计模式
- 存储库设计模式
- 采用代码优先开发的 Entity Framework ORM
使用示例解决方案,您可以按照下面的每个部分进行操作并自行进行实验。
先决条件
您应该:
- 具备 ASP.NET MVC 的工作知识
- 了解模型视图视图模型 (MVVM) 设计模式
- Visual Studio 已准备就绪
BlipBinding 案例研究解决方案
BlipBinding解决方案实施的案例研究是一个简单的应用程序,用于维护有关客户、他们的订单以及订单中的商品的信息。该应用程序的永久数据存储是 SQL Server 数据库。表格及其关系如下所示:
BlipBinding 数据库实体关系图
实体和关系
请注意,订单和商品之间的多对多关系是通过使用带有有效负载的合并表来实现的:除了维护订单和商品之间的关系之外,OrderItems表还包含有关订单中包含的商品、销售价格以及销售数量的信息。
显然,这不是一个完整的订单处理系统;它只是为了以熟悉的形式提供层次关系的示例。
数据库是使用 Entity Framework 代码优先设计创建和维护的。每个表及其与其他表的关系由BlipBinding解决方案的Blip.Entities项目中的类定义。让我们看看Customer和Order实体:
Blip.Entities\客户\客户.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Blip.Entities.Geographies;
using Blip.Entities.Orders;
namespace Blip.Entities.Customers
{
public class Customer
{
public Customer()
{
Orders = new HashSet<Order>();
}
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid CustomerID { get; set; }
[Required]
[MaxLength(128)]
public string CustomerName { get; set; }
[Required]
[MaxLength(3)]
public string CountryIso3 { get; set; }
[MaxLength(3)]
public string RegionCode { get; set; }
public virtual Country Country { get; set; }
public virtual Region Region { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
}
请注意以下特征:
ComponentModel DataAnnotations 用于识别数据库的关键字段并指定大小和其他选项。
客户和订单之间的一对多关系是通过由订单实体集合组成的虚拟成员字段创建的。
数据库中Customers和Countries之间所需的关系反映在用于保存值CountryIso3 的字段和用于标识关系Country 的字段中,该字段属于Country类型。
订单.cs
Order实体的定义方式类似:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Blip.Entities.Customers;
using Blip.Entities.Items;
namespace Blip.Entities.Orders
{
public class Order
{
public Order()
{
Items = new HashSet<Item>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid OrderID { get; set; }
[Required]
public Guid CustomerID { get; set; }
[Required]
public DateTime OrderDate { get; set; }
[Required]
[MaxLength(128)]
public string Description { get; set; }
public virtual ICollection<Item> Items { get; set; }
public virtual Customer Customer { get; set; }
}
}
注意:
订单只能属于一个客户,这反映在单个CustomerID字段和导航属性Customer中。
Orders和Items之间的一对多关系是通过Item实体集合的虚拟属性实现的。
数据库的数据上下文和实体框架代码优先迁移以及存储库方法位于Blip.Data项目中。
呈现数据
BlipBinding解决方案中的Blip.Web项目基于标准 .NET Framework MVC 模板,因此视图的布局基于默认的 Bootstrap CSS 样式和模板中包含的_layout.cshtml 。
出于本指南的目的,案例研究中有两个值得注意的视图,一个用于显示客户列表,另一个用于显示每个客户的订单列表。
客户/指数视图
客户列表的视图是一个简单的表格,显示有关客户的一些基本信息和一个用于导航到客户订单列表的Html.ActionLink帮助方法:
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~