nii*_*ico 6 asp.net-core-mvc asp.net-core asp.net-core-2.0 asp.net-core-mvc-2.0 asp.net-core-3.1
我有一个 ASP.net MVC Core 2(如果需要可以升级到 3)Web 应用程序。
有几个不同的类别,房东、租户、承包商 - 他们每个都有一个地址对象和其他不同的属性。
我有一个部分视图,它从每个视图传递地址对象。
<partial name="_AddressPartial" , model="@Model" />
Run Code Online (Sandbox Code Playgroud)
这很好用。但是,当发布表单时,每个地址字段都是平面发布的,因为地址的名称类似于“Street”,而不是“Address.Street” - 因为地址模型被传递给部分。因此模型绑定器正在寻找“街道”等,而不是作为地址对象的一部分。
我可以从部分所在的每个页面传递对象,并添加前缀“地址”。每个字段名称,但房东、承包商、租户等都是不同的类别,所以我需要每页不同的部分,这违背了这一点。
我也许可以使用带有 Address 的基类,然后从中派生所有其他类,并将基类绑定到部分?但这似乎只是为了部分工作而太过分了。
我可以将 Address 对象平铺到每个 ViewModel 中 - 这会在写入数据库时产生更多的工作(你不能只向 Dapper 传递一个 Address 模型,你必须手动编写一些 SQL 来进行更新),并创建大量重复。
如何在所有页面之间重复使用部分内容,保持干燥,并避免列出的问题。
我用谷歌搜索了一下,上面是我能找到的全部内容。我错过了什么吗?
当表单被发布时,每个地址字段都是平面发布的,因为地址的名称是“Street”,而不是“Address.Street” - 因为地址模型被传递给部分。因此模型绑定器正在寻找“街道”等,而不是作为地址对象的一部分。
要修复它,您可以尝试以下方法。
方法 1:如下设置HtmlFieldPrefix。"Address"
_AddressPartial.cshtml
@model Address
@{
Html.ViewData.TemplateInfo.HtmlFieldPrefix = "Address";
}
<div class="form-group">
<label asp-for="City" class="control-label"></label>
<input asp-for="City" class="form-control" />
<span asp-validation-for="City" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Street" class="control-label"></label>
<input asp-for="Street" class="form-control" />
<span asp-validation-for="Street" class="text-danger"></span>
</div>
@*other input fields*@
Run Code Online (Sandbox Code Playgroud)
方法 2:实现自定义模型绑定器以将数据绑定到Street
等属性。
地址类别
public class Address
{
public string City { get; set; }
public string Street { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
定制模型活页夹AddressBinder
// code logic here
// ...
var model = new Address();
if (bindingContext.ValueProvider.GetValue("City").FirstOrDefault() != null&& bindingContext.ValueProvider.GetValue("Street").FirstOrDefault() != null)
{
var city = bindingContext.ValueProvider.GetValue("City").FirstOrDefault();
var street = bindingContext.ValueProvider.GetValue("Street").FirstOrDefault();
model.City = city;
model.Street = street;
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
Run Code Online (Sandbox Code Playgroud)
将其应用到Address
财产上
[ModelBinder(BinderType = typeof(AddressBinder))]
public Address Address { get; set; }
Run Code Online (Sandbox Code Playgroud)
测试及结果
对于方法 1:
<div class="row">
<div class="col-md-4">
<form asp-action="NewContractor">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Cname" class="control-label"></label>
<input asp-for="Cname" class="form-control" />
<span asp-validation-for="Cname" class="text-danger"></span>
</div>
<partial name="_AddressPartial" model="@Model" />
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
对于方法 2:
public class Landlord
{
public string Name { get; set; }
[ModelBinder(BinderType = typeof(AddressBinder))]
public Address Address { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1071 次 |
最近记录: |