c# - .NET Core:不呈现 ViewModel 属性
问题描述
我正在使用 Razor 视图引擎开发 ASP.NET Core 2.0 Web 应用程序。首先,我试图通过互联网和 StackOverFlow 寻找解决方案,但其中任何一个都可以解决我的问题。让我们看看我们面临着什么:
我有一个相对简单的客户视图模型:
namespace MokaKukaMap.Application.Customers.ViewModels.Models
{
public class CustomerViewModel
{
public long Id { get; set; }
[Display(Name = "Név")]
[Required]
public string Name { get; set; }
[Display(Name = "Telefonszám")]
[Required]
public string PhoneNumber { get; set; }
}
}
如您所见,Name
andPhoneNumber
属性具有Display
指定的属性。我相应的部分视图 ( _NewCustomer.cshtml
) 如下:
@model MokaKukaMap.Application.Customers.ViewModels.Models.CustomerViewModel
<div class="col-lg-5 basic-surronder">
<form asp-controller="NewCustomer" asp-action="NewCustomer" class="well">
<div id="form-horizontal">
<div class="form-group">
<label asp-for="@Model.Name" class=""></label>
<div class="">
<input asp-for="@Model.Name" class="form-control">
<span asp-validation-for="@Model.Name" class="text-danger"> </span>
</div>
</div>
<div class="form-group">
<label asp-for="@Model.PhoneNumber" class=""></label>
<div class="">
<input asp-for="@Model.PhoneNumber" class="form-control">
<span asp-validation-for="@Model.PhoneNumber" class="text-danger"> </span>
</div>
</div>
</div>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<div class="">
<input type="submit" formnovalidate="formnovalidate" value="Új ügyfél hozzáadása" class="btn btn-primary" />
</div>
</div>
</form>
</div>
到目前为止,一切都很好。正如我已经提到的,我将此视图用作局部视图,因此我将她包含在NewCustomer.cshtml
主视图中,并带有以下行:
@Html.Partial("_NewCustomer")
位于_NewCustomer.cshtml
标准 Views/Shared 文件夹中。我想做的是将此部分视图放入特定文件夹,即Customers/Views 文件夹。为了解决这个问题,我做了一个CustomerViewLocationExpander
,如下所示:
public class CustomViewLocationExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
var viewLocationFormats = new[]
{
"~/Customers/Views/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/{0}.cshtml",
};
return viewLocationFormats;
}
public void PopulateValues(ViewLocationExpanderContext context)
{
context.Values["customviewlocation"] = nameof(CustomViewLocationExpander);
}
}
在 Startup.cs 中配置:
services.Configure<RazorViewEngineOptions>(options => options.ViewLocationExpanders.Add(new CustomViewLocationExpander()));
我的问题如下:如果_NewCustomer.cshtml
位于 Views/Shared 文件夹中,一切正常。但是,如果我将它放在我的自定义客户/视图文件夹中,则不会显示/呈现属性的名称,并且验证属性也根本不起作用。呈现两个输入字段是因为我看到以下表单:
我已经尝试解决我的问题,(但他们都没有帮助):
在启动时配置视图位置
services.Configure<RazorViewEngineOptions>(o => o.ViewLocationFormats.Add("/Customers/Views/{0}" + RazorViewEngine.ViewExtension));
当我包含部分视图时使用绝对路径:
@Html.Partial("~/Customers/Views/_NewCustomer.cshtml")
在我的“客户”文件夹中创建一个名为“共享”的文件夹并将我的部分视图放在那里:客户/视图/共享
删除所有“bin”和“obj”文件夹,清理然后重建解决方案
此外我意识到,如果部分视图位于自定义文件夹中,那么 VS2017 (IntelliSense) 无法识别 asp-net-core 特定的 html 标签,例如<form asp-controller=
只有当视图位于共享文件夹。
附加信息:
你觉得问题出在哪里?谢谢你的帮助!
解决方案
不确定这是否会帮助您解决实际问题,因为您可能需要更改很多东西。但我发现这种结构比您那里的结构更“干净”。我立即看到的问题是:
- 很难区分实际功能和设置/基础代码。是
Containers
一个特性还是与 Docker 有关?不知道,必须打开它。 - 现在的方式是,
IViewLocationExpander
您必须对每个功能名称进行“硬编码”,因为它们都散布在各处……不太酷。
我的建议是将结构更改为:
- 功能(将视图重命名为功能,正常保留共享文件夹。)
- 顾客
- 控制器
- 意见
- 顾客
然后,你ViewLocationExpander
像这样配置你:
public class ViewLocationExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
// {1} is Controller, {0} is View Name
return new []
{
"/Features/{1}/Views/{0}.cshtml", // Finds the Customer View folders
"/Features/{1}/{0}.cshtml", // finds the Home views.. they are in root of the folder.. so no need for Views
"/Features/Shared/{0}.cshtml" // Layouts
};
}
public void PopulateValues(ViewLocationExpanderContext context)
{
}
}
这样,您可以Product
使用它自己的Views
文件夹添加新功能,例如,它会自动被拾取。这是我在设置中使用的结构的图像:
编辑:这是我在 Github joaopgrassi/custom-razorview-location上的解决方案
另外,我真的不明白在一个单独的项目中拥有 ViewModel 的意义。ViewModel 的全部目的是为 UI 服务。ViewModel 上没有任何 DDD,带有公共设置器。也许我误解了你..但我肯定会更深入地研究。DDD 是丰富的,通常是不可变的实体。而 ViewModel 只是 poco 类,只是为了传输数据。
推荐阅读
- reactjs - 反应警报重复 2 次
- reactjs - PropType.shape({}) 失败警告:无效类型
- python - PySide6 中 QML 的后端是否有更清洁的方法?
- javascript - 获取中的状态 201
- java - Logcat 错误:“java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView”尝试使用 ListView
- python - 向量化文本作为 RNN 的输入
- python-3.x - 为什么在此 python 代码中出现“并非所有参数都在字符串格式化期间转换”的错误?
- django - 服务器上的 DRF 项目静态文件问题
- c# - MediatR 库:遵循 DRY 原则
- reactjs - 谁能解释为什么这个 setinterval 运行 21 秒。数学说它应该运行 20