如何在MVC中通过ViewBag向视图传递单条数据及列表数据?
在ASP.NET MVC中用ViewBag传递单行+多行数据到View的实现方案
看起来你已经在控制器里完成了数据获取并通过ViewBag传递的核心逻辑,我先帮你把控制器代码补全并格式化,然后再展示View层怎么渲染这些数据,最后给你个更健壮的优化方案~
第一步:补全并格式化控制器代码
你原来的代码应该是没写完,这里帮你补全完整的Detail方法:
public ActionResult Detail(string id) { // 获取单行销售单据数据 ViewBag.SalesDocument = logisticsContext.Sap_Sales_Order_Report_qas .Where(x => x.sales_document == id) .SingleOrDefault(); // 获取多行配送计划数据并按配送日期排序 var existingSchedule = sipContext.OrderDeliverySchedules .Where(o => o.so_no == id) .OrderBy(o => o.split_date) .ToList(); ViewBag.DeliverySchedule = existingSchedule; return View(); }
第二步:View层渲染数据
在对应的View文件里,我们分两部分渲染:单行的销售单据详情,和多行的配送计划列表,同时要做空值判断避免报错:
渲染单行销售单据
@* 先判断数据是否存在,避免空引用异常 *@ @if (ViewBag.SalesDocument != null) { var salesDoc = ViewBag.SalesDocument; <div class="sales-doc-container"> <h3>销售单据详情</h3> <div class="detail-row"> <span class="label">单据编号:</span> <span>@salesDoc.sales_document</span> </div> <div class="detail-row"> <span class="label">客户名称:</span> <span>@salesDoc.customer_name</span> </div> <!-- 这里根据你的实体类属性,添加更多需要展示的字段 --> </div> } else { <div class="alert alert-warning">未找到对应编号的销售单据</div> }
渲染多行配送计划列表
@* 判断是否有配送计划数据 *@ @if (ViewBag.DeliverySchedule != null && ViewBag.DeliverySchedule.Any()) { <div class="schedule-table-container mt-4"> <h3>配送计划列表</h3> <table class="table table-bordered"> <thead> <tr> <th>配送日期</th> <th>配送数量</th> <th>计划状态</th> <!-- 根据你的实体类属性添加更多表头 --> </tr> </thead> <tbody> @foreach (var schedule in ViewBag.DeliverySchedule) { <tr> <td>@schedule.split_date.ToString("yyyy-MM-dd")</td> <td>@schedule.quantity</td> <td>@schedule.status</td> <!-- 添加更多需要展示的字段 --> </tr> } </tbody> </table> </div> } else { <div class="alert alert-info">暂无配送计划数据</div> }
优化建议:使用强类型ViewModel代替ViewBag
虽然ViewBag用起来方便,但它是动态类型,没有编译时检查,很容易因为拼写错误或者属性名变更导致运行时错误。更推荐用强类型ViewModel来封装数据:
1. 创建ViewModel类
public class SalesDocumentDetailViewModel { // 单行销售单据数据 public Sap_Sales_Order_Report_qas SalesDocument { get; set; } // 多行配送计划数据 public List<OrderDeliverySchedule> DeliverySchedules { get; set; } }
2. 修改控制器代码
public ActionResult Detail(string id) { var salesDoc = logisticsContext.Sap_Sales_Order_Report_qas .Where(x => x.sales_document == id) .SingleOrDefault(); var deliverySchedules = sipContext.OrderDeliverySchedules .Where(o => o.so_no == id) .OrderBy(o => o.split_date) .ToList(); // 组装ViewModel var viewModel = new SalesDocumentDetailViewModel { SalesDocument = salesDoc, DeliverySchedules = deliverySchedules }; return View(viewModel); }
3. 修改View代码
在View文件顶部指定模型类型,之后就可以用强类型访问数据,IDE还会有智能提示:
@model YourNamespace.SalesDocumentDetailViewModel @if (Model.SalesDocument != null) { <div class="sales-doc-container"> <h3>销售单据详情</h3> <div class="detail-row"> <span class="label">单据编号:</span> <span>@Model.SalesDocument.sales_document</span> </div> <!-- 其他字段 --> </div> } @if (Model.DeliverySchedules != null && Model.DeliverySchedules.Any()) { <div class="schedule-table-container mt-4"> <h3>配送计划列表</h3> <table class="table table-bordered"> <thead> <tr> <th>配送日期</th> <th>配送数量</th> </tr> </thead> <tbody> @foreach (var schedule in Model.DeliverySchedules) { <tr> <td>@schedule.split_date.ToString("yyyy-MM-dd")</td> <td>@schedule.quantity</td> </tr> } </tbody> </table> </div> }
这样不仅代码更健壮,后期维护也更省心~
内容的提问来源于stack exchange,提问作者Kerzoz
相关产品推荐
相关产品推荐

