c# - 模型内的列表项在发布时始终为空 - Asp.net MVC

标签 c# asp.net asp.net-mvc-4 razor

我正在尝试发布包含 List<> 项目的模型,如下所示:

public class AddSubscriptionPlanModel
{
    public AddSubscriptionPlanModel()
    {
        AllFeatures = new List<Feature>();
    }
    public int Id { get; set; }
    public int SubscriptionPlanId { get; set; }
    public int SubscriptionId { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }
    [Display(Name = "No Of Users")]
    public int? NoOfUsers { get; set; }
    [Display(Name = "Duration Type")]
    public DurationType DurationType { get; set; }
    public int Duration { get; set; }
    public decimal Amount { get; set; }
    public int SubscriptionPlanTrailId { get; set; }
    public int FeatureId { get; set; }
    public DateTime CreatedDateUtc { get; set; }
    public DateTime LastUpdatedUtc { get; set; }
    public int CreatedBy { get; set; }
    public int LastUpdatedBy { get; set; }    
    public List<Feature> AllFeatures { get; set; }
}

我正在填充 get 方法的所有必填字段并从数据库中提供列表

public ActionResult Mapping(int id)
{        
    var features = FeatureManager.GetAllFeatures();
    var model = new Ejyle.DevAccelerate.Web.App.Models.SubscriptionPlan.AddSubscriptionPlanModel();

    model.AllFeatures = features;
    model.Id = id;
    model.SubscriptionId = id;
    model.NoOfUsers = 20;
    model.SubscriptionPlanId = 1;
    model.SubscriptionPlanTrailId = 1;
    model.Amount = 1000;
    model.CreatedBy = 1;
    model.LastUpdatedBy = 1;
    model.FeatureId = 1;
    model.Duration = 20;

    return View(model);
}

我的 View 代码如下所示:

@using (Html.BeginForm("Mapping", "SubscriptionPlans", FormMethod.Post))
{
    @Html.HiddenFor(model => model.Id)
    @Html.HiddenFor(model => model.Amount)
    @Html.HiddenFor(model => model.Duration)
    @Html.HiddenFor(model => model.FeatureId)
    @Html.HiddenFor(model => model.CreatedBy)
    @Html.HiddenFor(model => model.LastUpdatedBy)
    @Html.HiddenFor(model => model.NoOfUsers)
    @Html.HiddenFor(model => model.SubscriptionId)
    @Html.HiddenFor(model => model.SubscriptionPlanId)
    @Html.HiddenFor(model => model.SubscriptionPlanTrailId)
    @Html.HiddenFor(model => model.AllFeatures)
    <table class="table table-striped">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.IsActive)
                </th>
            </tr>
        </thead>
        <tbody>
            @for (int i=0; i < Model.AllFeatures.Count; i++)
            {
                <tr>
                    @Html.HiddenFor(model => model.AllFeatures[i].Id)
                    @Html.HiddenFor(model => model.AllFeatures[i].Name)
                    @Html.HiddenFor(model => model.AllFeatures[i].IsActive)
                    <td>
                        @Html.TextBoxFor(model => model.AllFeatures[i].Id)
                    </td>
                    <td>
                        @Html.TextBoxFor(model => model.AllFeatures[i].Name)
                    </td>
                    <td>
                        @Html.EditorFor(model => model.AllFeatures[i].IsActive)
                    </td>
                </tr>
            }
        </tbody>
    </table>
    <input type="submit" class="btn btn-success" value="Submit" name="Submit"/>
}

在查看时,列表项正确呈现,甚至我也可以编辑这些字段。
但是在发布时,除了 AllFeatures 列表项属性始终显示 count = 0 之外,所有属性都具有值。

编辑 1:这是我的 View 在渲染功能时的样子

enter image description here

编辑 2:

方法的签名发布到:

[HttpPost]
public ActionResult Mapping(AddSubscriptionPlanModel model)
{       
}

最佳答案

But On post, all properties have the value except AllFeatures list item property which always shows count = 0.

AllFeaturesFeature 的通用列表。当你这样做时:

@Html.HiddenFor(model => model.AllFeatures) 

Razor View 引擎将呈现这个:

<input id="AllFeatures" 
       name="AllFeatures" 
       type="hidden" 
       value="System.Collections.Generic.List`1[Namespace.Feature]">
       <!--Where Namespace is the Namespace where Feature is defined. -->

换句话说,HiddenFor 调用项目上的 ToString() 并将其放入 input 标签的 value 属性。

POST 后会发生什么

当您发布表单时,DefaultModelBinder 正在寻找一个名为 AllFeatures 但类型为 string 的属性,因此它可以将其分配给它:

System.Collections.Generic.List`1[Namespace.Feature]

它没有找到一个,因为您的模型没有 String 类型的 AllFeatures,所以它只是忽略它并绑定(bind)所有其他属性。

AllFeatures list item property which always shows count = 0.

是的,它会,这不是您发布的 AllFeatures 列表,而是来自构造函数的列表,它显然是一个计数为 0 的空列表:

public AddSubscriptionPlanModel()
{
    AllFeatures = new List<Feature>();
}

我不确定您为什么要将所有功能发送到客户端(浏览器),然后您需要将其发送回服务器。

解决方案

要解决此问题,只需删除此行:

@Html.HiddenFor(model => model.AllFeatures)

现在它不会在绑定(bind)过程中造成任何困惑,MVC 会将循环中的项目绑定(bind)到 AllFeatures 属性。

事实上,据我所知,您真正需要的唯一代码是这个(如果您出于其他原因需要隐藏字段,我可能是错的。但如果您只是希望用户编辑AllFeatures,您不需要任何隐藏字段):

@for (int i = 0; i < Model.AllFeatures.Count; i++)
{
    <tr>
        <td>
            @Html.TextBoxFor(model => model.AllFeatures[i].Id)
        </td>
        <td>
            @Html.TextBoxFor(model => model.AllFeatures[i].Name)
        </td>
        <td>
            @Html.EditorFor(model => model.AllFeatures[i].IsActive)
        </td>
    </tr>
}

关于c# - 模型内的列表项在发布时始终为空 - Asp.net MVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44989007/

相关文章:

c# - 如何将 'quick steps' 样式控件添加到Outlook 2010 功能区?

c# - UWP - Splitview 定义相对于 OpenPaneLength 的值

javascript - Flex Grid 未在 Orchard CMS 中呈现

c# - 重定向网址不正确

c# - 为什么在使用 Entity Framework 6.x 通过 SqlQuery 从 View 中获取数据时不使用我的 ColumnAttribute?

c# - 如何将 void 返回扩展方法传递给动态返回扩展方法?

c# - LINQ 查询匹配两个项目列表

c# - 将值转换为仅显示一位小数

ASP.Net MVC, "Register"登录表单中的链接始终重定向到登录页面

c# - 链接 Task.Factory.FromAsync 和 ContinueWith 与等待