ASP.NET Core MVC中如何将Dataset整合进自定义ViewModel以实现单视图模型复用
这其实是ASP.NET Core MVC里非常常见的需求——用一个ViewModel来整合业务数据和表单交互字段,我来一步步帮你实现:
第一步:修改你的MyViewModel,添加DataSet属性
直接在现有的ViewModel里增加一个存储数据集的属性,这样就能把表格数据和表单字段放在同一个模型里。另外建议遵循C#的命名规范,把属性名首字母大写:
using System.ComponentModel.DataAnnotations; using System.Data; // 别忘了引入Data命名空间,不然DataSet会报错 namespace WebApplication4.Models { public class MyViewModel { public string MyRadioField { get; set; } [Required] public string IncomeType { get; set; } // 修正首字母大写,符合命名规范 // 添加存储交易数据的DataSet属性 public DataSet TransactionDataSet { get; set; } // 如果你只用到DataSet里的Tables[0],也可以直接存DataTable,更简洁: // public DataTable TransactionsTable { get; set; } } }
第二步:调整控制器,传递整合后的ViewModel
原来你可能直接把DataSet传给视图,现在需要实例化MyViewModel,把DataSet赋值给它的属性,同时处理表单字段的绑定(如果是Post请求的话):
using System.Data; using Microsoft.AspNetCore.Mvc; using WebApplication4.Models; namespace WebApplication4.Controllers { public class HomeController : Controller { public IActionResult Index() { // 假设这是你获取DataSet的逻辑(比如从数据库查询) DataSet transactionData = GetTransactionDataFromDB(); // 实例化ViewModel并赋值 var viewModel = new MyViewModel { TransactionDataSet = transactionData, // 可以在这里给表单字段设置默认值 // MyRadioField = "Option1" }; return View(viewModel); } // 处理表单提交的Post方法 [HttpPost] public IActionResult Index(MyViewModel viewModel) { if (ModelState.IsValid) { // 这里写表单提交的业务逻辑,比如保存IncomeType等 // ... // 重新加载交易数据,确保表格能正常显示 viewModel.TransactionDataSet = GetTransactionDataFromDB(); return View(viewModel); } // 验证失败时,也要重新加载数据,避免表格为空 viewModel.TransactionDataSet = GetTransactionDataFromDB(); return View(viewModel); } // 模拟从数据库获取DataSet的方法 private DataSet GetTransactionDataFromDB() { // 这里替换成你实际的数据获取逻辑 var ds = new DataSet(); // 假设已经填充了Tables[0]的数据 return ds; } } }
第三步:修改视图,使用整合后的ViewModel
把视图的@model改成MyViewModel,然后调整表格的数据源,同时可以添加表单字段的绑定:
@using System.Data; @using WebApplication4.Models; @model MyViewModel; <!-- 表单部分:绑定ViewModel的表单字段 --> <form asp-action="Index" method="post" class="mb-4"> <div class="form-group"> <label>Radio Option:</label> <div> <input type="radio" asp-for="MyRadioField" value="Option1" /> Option 1 <input type="radio" asp-for="MyRadioField" value="Option2" /> Option 2 </div> </div> <div class="form-group"> <label asp-for="IncomeType"></label> <input asp-for="IncomeType" class="form-control" /> <span asp-validation-for="IncomeType" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> <!-- 表格部分:从ViewModel的DataSet里取数据 --> <table class="table table-striped"> <thead class="thead-dark"> <tr> <th>Account</th> <th>Amount</th> <th>Date</th> <th>Type</th> <th>View</th> </tr> </thead> <tbody> <!-- 增加空值判断,避免空引用异常 --> @if (Model.TransactionDataSet != null && Model.TransactionDataSet.Tables.Count > 0) { foreach(DataRow row in Model.TransactionDataSet.Tables[0].Rows) { <tr> <td>@row["account"]</td> <td>@row["amount"]</td> <td>@row["date"]</td> <td>@row["type"]</td> <td> <button class="btn btn-primary btn-block" onclick="window.location.href='/HOME/TransactionInfo?id=@row["transactionid"]'"> View details </button> </td> </tr> } } else { <tr> <td colspan="5" class="text-center">No transactions found</td> </tr> } </tbody> </table>
额外小提示
如果你的场景里只用到DataSet的第一个表,建议直接在ViewModel里存DataTable类型的属性(比如public DataTable TransactionsTable { get; set; }),这样视图里可以直接写Model.TransactionsTable.Rows,少一层嵌套,代码更简洁。
内容的提问来源于stack exchange,提问作者mohan
相关产品推荐
相关产品推荐

