简体   繁体   English

将子 object 从不同模型的视图传递到部分视图,在发布表单时将其绑定

[英]Pass sub object to partial view from views with different models, have it bind when form is posted

I have an ASP.net MVC Core 2 (can upgrade to 3 if required) web app.我有一个 ASP.net MVC Core 2(如果需要可以升级到 3)web 应用程序。

There are several different classes, landlord, tenant, contractor - they each have an address object, and other different properties.有几个不同的类别,房东、租户、承包商——他们每个都有一个地址 object 和其他不同的属性。

I have a partial view that is passed the address object from each view.我有一个部分视图,每个视图都传递了地址 object。

<partial name="_AddressPartial" , model="@Model" />

This works fine.这工作正常。 But when the form is posted, each address field is posted flat, as the names of the address are things like "Street", not "Address.Street" - because the address model is passed to the partial.但是当表单发布时,每个地址字段都是平铺的,因为地址的名称是“Street”,而不是“Address.Street” - 因为地址 model 被传递给部分。 So the model binder is looking for "Street" etc, not as part of an Address object.所以 model 活页夹正在寻找“街道”等,而不是作为地址 object 的一部分。

I could pass the object from each page the partial is on, and prefix "Address."我可以从部分所在的每个页面传递 object,并添加前缀“地址”。 to each field name, but Landlord, Contractor, Tenant etc are all different classes so I'd need a different partial per page which defeats the point.到每个字段名称,但房东、承包商、租户等都是不同的类,所以我需要每页有不同的部分,这违背了这一点。

I might be able to use a base class with Address, then derive all the other classes from that, and bind the base class to the partial?我也许可以使用带有地址的基础 class,然后从中派生所有其他类,并将基础 class 绑定到部分? But that seems like overkill just to get a partial working.但这似乎只是为了部分工作而过大。

I could flatten the Address object into each ViewModel - this would create significantly more work when writing to the database though (you can't just pass Dapper an Address model, you'll have to manually write some SQL for the update), and create lots of repetition.我可以将地址 object 展平到每个 ViewModel 中——尽管这样在写入数据库时会产生更多的工作(你不能只将地址 model 传递给 Dapper,你必须手动编写一些 Z9778840A01010CB30C982Z876 更新)很多重复。

How can I re-use a partial between all the pages, keep it DRY, and avoid the listed problems.如何在所有页面之间重复使用部分,保持干燥,并避免列出的问题。

I've googled it and the above is all I could find.我已经用谷歌搜索过了,以上就是我能找到的所有内容。 Am I missing something?我错过了什么吗?

when the form is posted, each address field is posted flat, as the names of the address are things like "Street", not "Address.Street" - because the address model is passed to the partial.当表单发布时,每个地址字段都是平铺的,因为地址的名称是“Street”,而不是“Address.Street” - 因为地址 model 被传递给部分。 So the model binder is looking for "Street" etc, not as part of an Address object.所以 model 活页夹正在寻找“街道”等,而不是作为地址 object 的一部分。

To fix it, you can try following approaches.要修复它,您可以尝试以下方法。

Approach 1 : set HtmlFieldPrefix with "Address" in _AddressPartial.cshtml as below.方法 1 :在_AddressPartial.cshtml中使用"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*@

Approach 2 : implement a custom model binder to bind data to Street etc properties.方法 2 :实现自定义 model绑定器将数据绑定到Street等属性。

Address class地址 class

public class Address
{
    public string City { get; set; }

    public string Street { get; set; }
}

Custom model binder AddressBinder自定义 model 绑定器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;

Apply it to Address property将其应用于Address属性

[ModelBinder(BinderType = typeof(AddressBinder))]
public Address Address { get; set; }

Test and Result测试和结果

For approach 1:对于方法 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> 

在此处输入图像描述

For approach 2:对于方法 2:

public class Landlord
{
    public string Name { get; set; }
    [ModelBinder(BinderType = typeof(AddressBinder))]
    public Address Address { get; set; }
}

在此处输入图像描述

I'm a bit late to the party, but I think you should use the attribute for instead of model in the partial element, similarly to:我参加聚会有点晚了,但我认为您应该在partial元素中使用属性for而不是model ,类似于:

<partial name="_AddressPartial" for="@Model.Address" />

Assuming Model.Address is a property that stores an instance of your shared Address class.假设Model.Address是一个存储共享Address class 实例的属性。 Thus, ASP.NET Core will properly map the fields' name with the prefix Address .因此, ASP.NET 核心将正确地 map 带有前缀Address的字段名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有来自不同模型的数据但显示在同一视图上的两个局部视图 - Two partial views with data from different models but displayed on a same View 当涉及不同型号时,如何将主视图值和部分视图值传递给 controller? - How to pass main and partial views values to the controller when different models are involved? .Net core MVC - 设置局部视图以绑定到多个模型 - .Net core MVC - Setting up a partial view to bind to multiple models 从部分视图提交时无法获取序列化表单数据? - Unable to get serialize form data when submit from partial view? 将 ModelExpression 从标签助手传递到局部视图 - Pass ModelExpression from a Tag Helper to a Partial View 我有一个从视图中检索的值,我必须通过 2 个视图传递该值,但这是将 null 值传递给变量 asp.net - I have a value that i retrieve from a view and i have to pass that value through 2 views, but that is passing a null value to the variabel asp.net 如何使用不同的模型将数据传递给局部视图? - How to pass data to a partial view using a different model? 如何以查询字符串格式将发布的数据绑定为x-www-form-urlencoded? - How do I bind posted data as x-www-form-urlencoded when it comes in querystring format? 从局部视图中的 PageModel 获取 Object - Get Object from PageModel in Partial View 发布部分视图表格 - Post partial view form
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM