我正在开发 ASP.NET Core 6 MVC Web 应用程序。我创建了两个模型(以及与我的问题无关的其他模型),每个模型都有自己的属性(这里不会提及这些属性,因为它没有多大帮助)。
长话短说,经过对 Google 和其他地方的彻底研究后,我得出了这样的结论:为了我想要的,我需要创建一个视图模型(我们称之为
CompositeModel
)。
这是代码:
using Project_Name.Models;
namespace Project_Name.ViewModels
{
public class CompositeModel
{
public ShoArt? ShAr { get; set; }
public FarSho? FaSh { get; set; }
public List<string>? ShArColumns { get; set; }
public List<string>? FaShColumns { get; set; }
public List<string>? SelectedColumns { get; set; }
public List<ShoArt>? ShArData { get; set; }
public List<FarSho>? FaShData { get; set; }
public string? SelectedModelName { get; set; }
}
}
简单地解释一下,我想要的是通过我们拥有的两个模型进行高级过滤(将来可能会添加更多模型,但目前只有两个模型)。
用户将从数据库中观察为他们列出的这两个模型的所有列,他们可以通过选中或取消选中其复选框来选择他们想要在结果页面中看到的一个,但整个目的是将这两个模型的列连接起来互相建模。
注意:不确定它是否会有所帮助,但稍后,用户必须能够通过实现自己的自定义条件来对这些数据进行一些查询,以获得完全符合他们需求的数据。例如,如果我们选择的任何表(模型)中存在具有该名称的列,则选择“年龄”列的范围。就像告诉我们的网络应用程序:“我只想要 30 到 40 岁的人”或类似的话。
这是我们的
Index.cshtml
代码,负责显示这两个模型的所有列:FilterController
这是
@model Project_Name.ViewModels.CompositeModel
@{
ViewData["Title"] = "Index";
}
<!DOCTYPE html>
<html>
<head>
<title>Display Data</title>
</head>
<body>
<h1>Data Display</h1>
<form method="post" asp-action="DisplayTable">
<h2>Select Model</h2>
<label>
Select Model:
<select name="SelectedModelName">
<option value="ShAr">ShAr</option>
<option value="FaSh">FaSh</option>
<!-- Add other model options as needed -->
</select>
</label>
<h2>Select Columns</h2>
<label>
ShAr:
@foreach (var column in Model.ShArColumns!)
{
<input type="checkbox" name="selectedColumns" value="ShAr.@column" /> @column
}
</label>
<label>
FaSh:
@foreach (var column in Model.FaShColumns!)
{
<input type="checkbox" name="selectedColumns" value="FaSh.@column" /> @column
}
</label>
<input type="submit" value="Display Table" />
</form>
</body>
</html>
的代码:
FilterController
最后,这是负责为我们显示所选列及其数据的
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using yadegaranAlpha.Context;
using System.Linq;
using yadegaranAlpha.Models;
using yadegaranAlpha.ViewModels;
using DocumentFormat.OpenXml.Spreadsheet;
using NuGet.Protocol.Plugins;
//using AspNetCore;
namespace Project_Name.Controllers
{
public class FilterController : Controller
{
private readonly ApplicationDbContext _context;
public FilterController(ApplicationDbContext context)
{
_context = context;
}
public IActionResult Index()
{
var shArColumns = GetPropertyNames<ShoArt>();
var faShColumns = GetPropertyNames<FarSho>();
var compositeModel = new CompositeModel
{
ShArColumns = shArColumns,
FaShColumns = faShColumns,
// Initially empty, will be populated based
// on user selection
SelectedColumns = new List<string>()
};
return View(compositeModel);
}
// Helper method to get property names of a type
private List<string> GetPropertyNames<T>()
{
return typeof(T).GetProperties().Select(p => p.Name).ToList();
}
//DisplayTable ActionResult
[HttpPost]
public async Task<IActionResult> DisplayTable(CompositeModel model)
{
model.SelectedColumns = model.SelectedColumns ?? new List<string>();
List<object> combinedData = new List<object>();
var shArData = await _context.shoart.ToListAsync();
var faShData = await _context.farsho.ToListAsync();
foreach (var item in shArData)
{
combinedData.Add(item);
}
foreach (var item in faShData)
{
combinedData.Add(item);
}
model.ShArData = shArData;
model.FaShData = faShData;
return View("DisplayTable", model);
}
}
}
文件的代码:
DisplayTable.cshtml
有什么问题吗?
问题是,当我选择 FaSh modelName 时,它只会显示该 modelName 的数据,而其他 modelName 的数据(在本例中为 ShAr)显示空数据单元格,反之亦然。 只要注意下面的图片:
在上图中,我从这两个模型中选择了我想要的那些列。 (其他列已用红线隐藏)。
下图是用户单击“显示表格”按钮时的结果。请记住,出于安全原因,我尝试隐藏数据,但您可以相信我,带有红色矩形的部分包含数据:
如您所见,因为我们选择的 modelName 是 ShAr,因此只有与 ShAr modelName 相关的数据才会显示,反之亦然。 我可以对 FaSh modelName 做同样的事情,这次与该 modelName 相关的那些列的数据将被显示。
我希望它们都能毫无问题地显示。 我不知道,但就像在 ASP.NET CORE 中,我们只能在一个视图中选择一个 modelName,不幸的是,如果我只能在最终结果视图中混合这两个模型,那么我就不会有任何处理问题.
如何在我的应用程序中处理这个问题?
我也尝试过这些资源,但没有一个围绕我的问题。
在一个视图中使用多个模型ASP MVC 3 中一个视图中的两个模型MVC 一个视图中的多个模型ASP.NET Core MVC - 一个视图中多个模型的推荐方式让我为您提供更多可能有用的详细信息。 另一方面,我的 ShAr 表有 1170 条记录,我的 FaSh 表有 2456 条记录。 老实说,只要这两个表的记录数不相等,将它们并排显示是没有意义的。 FaSh 表通过外键连接到 ShAr 表。 我不知道我哪里出了问题,但我需要帮助来理解实现我想要的逻辑。 到目前为止,我创建的这个还不够并且没有完成这项工作。
我真的非常感谢任何帮助和协助。
在您的判断中仅检索一个模型,这就是为什么您无法在表中显示另一个模型。 由于您对 SelectedModelName 的判断在这种情况下没有任何意义,因此我删除了该判断,并请稍后在您的应用程序中考虑该判断。而且您还提到这两个表格并排显示没有意义,我这样显示表格。
显示表视图
@using System.ComponentModel; @model Project_Name.ViewModels.CompositeModel @{ ViewData["Title"] = "Display Table"; } <!DOCTYPE html> <html> <head> <title>Display Table</title> <!-- Include any necessary styles or scripts here --> </head> <body> <h1>Customized Data Display</h1> <table class="table table-sm"> <thead> <tr> @foreach (var column in Model.SelectedColumns) { <th>@column</th> } </tr> </thead> <tbody> @if (Model.SelectedModelName == "ShAr" && Model.ShArData != null) { foreach (var item in Model.ShArData) { <tr> @foreach (var column in Model.SelectedColumns) { <td>@GetColumnValue(item, column)</td> } </tr> } } else if (Model.SelectedModelName == "FaSh" && Model.FaShData != null) { foreach (var item in Model.FaShData) { <tr> @foreach (var column in Model.SelectedColumns) { <td>@GetColumnValue(item, column)</td> } </tr> } } </tbody> </table> @functions { public string GetColumnValue(object item, string columnName) { if (item == null) { return ""; } try { // Extract the actual property name from the full columnName var actualPropertyName = columnName.Split('.').LastOrDefault(); var property = TypeDescriptor.GetProperties(item).Find(actualPropertyName, true); if (property != null) { var value = property.GetValue(item); // Log the values for debugging Console.WriteLine($"Property: {actualPropertyName}, Value: {value}"); return value?.ToString() ?? ""; } return ""; } catch (Exception ex) { // Log the exception Console.WriteLine($"Exception: {ex.Message}"); return ""; } } } </body> </html>
其他代码保持不变。
测试