C# 模型正确显示,但返回空

C# 模型正确显示,但返回空,c#,asp.net-mvc-3,forms,razor,C#,Asp.net Mvc 3,Forms,Razor,我用强类型模型填充了一个局部视图。在这个局部视图中是一个窗体。当我提交表单时,它告诉我模型中的对象为空,即使它们不是空的,因为局部视图基于同一模型渲染了所有元素 更具体地说,我在返回所有复选框时遇到困难。如果你看我的控制器,你可以看到我检查公司选项是否为空,每次我运行程序时,它打印的东西都是空的,这意味着它是空的 型号: public class Company { public string Name { get; set; } public string DatabaseNa

我用强类型模型填充了一个局部视图。在这个局部视图中是一个窗体。当我提交表单时,它告诉我模型中的对象为空,即使它们不是空的,因为局部视图基于同一模型渲染了所有元素

更具体地说,我在返回所有复选框时遇到困难。如果你看我的控制器,你可以看到我检查公司选项是否为空,每次我运行程序时,它打印的东西都是空的,这意味着它是空的

型号:

public class Company
{
    public string Name { get; set; }
    public string DatabaseName { get; set; }
    public CompanyOptions CompanyOptions;
}

 public class CompanyOptions
    {

        public CompanyLicenseOptions CompanyLicenseOptions { get; set; }
    }

 public class CompanyLicenseOptions
    {
        public List<CompanyLicenseOption> CompanyLicenseOptionsList;
}
生成的HTML:

<input class="licenses" data-val="true" disabled="" id="CompanyOptions_CompanyLicenseOptions_CompanyLicenseOptionsList_0__IsLicensed" name="CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[0].IsLicensed" type="checkbox" value="true" /><input name="CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[0].IsLicensed" type="hidden" value="false" />
职位:


您应该使用foreach循环,而不是简单的for,这样:

@using (Html.BeginForm("Action", FormMethod.Post))
{
    foreach (var option in Model.CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList)
    {
        @Html.CheckBoxFor(o => o.IsLicensed, checkboxHtmlAttributes);
        <label for="@option.LicenseName">@option.LicenseName</label>                                                                                       
        <br/>
    } 
    @Html.HiddenFor(model => model.DatabaseName)
    <input id="submit_licenses" type="submit" style="display:none;" />
}
@使用(Html.BeginForm(“Action”,FormMethod.Post))
{
foreach(Model.CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptions列表中的var选项)
{
@CheckBoxFor(o=>o.IsLicensed,checkboxHtmlAttributes);
@option.LicenseName

} @Html.HiddenFor(model=>model.DatabaseName) }
您的复选框已禁用,因此不会向服务器发送任何内容。这就是HTML的工作原理。禁用的元素永远不会被发送。所以去掉这个属性

如果要阻止用户修改值,但初始值却被发送到服务器,请使用
只读
属性,而不是
禁用

我在代码中看到的另一个问题是
CompanyLicenseOptionsList
集合字段。它应该是具有公共getter和setter的属性:

public class CompanyLicenseOptions
{
    public List<CompanyLicenseOption> CompanyLicenseOptionsList { get; set; }
}

更新:


现在,您已经修复了缺少getter和setter的问题,剩下的就是确保介入此对象图的所有模型都具有默认(无参数)构造函数。如果您希望它们显示为操作参数,这是一个要求,因为否则默认的模型绑定器将不知道如何实例化它们。如果由于某种原因,您无法向所有对象添加默认构造函数,我强烈建议您修改对象层次结构,并立即开始使用视图模型。

由于所有这些复选框的端点都是
列表,您需要确保在使用前对其进行实例化:

public class CompanyOptions
{
    public CompanyLicenseOptions CompanyLicenseOptions { get; set; }
}
public class CompanyLicenseOptions
{
    public List<CompanyLicenseOption> CompanyLicenseOptionsList;
    public CompanyLicenseOptions() 
    {
         CompanyLicenseOptionsList = new List<CompanyLicenseOption>();
    }
}
公共类公司选项
{
public CompanyLicenseOptions CompanyLicenseOptions{get;set;}
}
公共类公司名称
{
公开上市公司LicenseOptionsList;
上市公司股票期权()
{
CompanyLicenseOptions列表=新列表();
}
}

编辑:为了确保读者获得正确的答案上下文并避免混淆,我复制了我上面的操作码。

我认为
@Html.CheckBoxFor(model=>model.CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptions.CompanyLicenseOptions列表[I].IsLicensed,checkboxHtmlAttributes)
将产生模型绑定器所期望的不正确的命名约定。复选框的呈现HTML标记是什么?您的提交按钮似乎被隐藏(
style=“display:none;”“
)那么您如何提交此表单?你在用javascript吗?AJAX还有别的吗?您能展示提交此表单的真实代码吗?@AdrianRefuerzo,不,它不会产生错误的命名约定。是的,我正在使用JS作为按钮。@Johannes,那么您还在等什么?我们无法读懂你的心思。这个js在哪里?有机会看到它吗?在我提交表单时,它没有被禁用,但出于测试目的,我完全删除了它,但问题仍然存在。你能展示一下你在FireBug中看到的吗?POST请求的确切负载?好的,POST负载看起来很好,并且遵守命名约定。我用我刚刚注意到的代码中的另一个问题更新了我的答案。这个getter/setter很好。不幸的是,行为没有改变。您的
CompanyLicenseOption
类中的
IsLicensed
布尔字段如何?你确定它有一个公众的接受者和接受者吗?顺便说一下,我还注意到您的控制器操作是
void
。通常,控制器操作应返回
ActionResult
。我不认为这与您的问题有关,我只是出于良好实践的考虑提一下。-1,默认模型绑定器无法处理字段。只有属性。因此,使用这种方法所得到的只是一个空集合,而不是NULL。您将永远无法绑定来自视图的值。更多细节请参见我的答案。我只是使用了OP中提供的内容,Darin。我很感激你申请在SOBut发布的原始能量,但是OP提供的是错误的!所以使用它是错误的。这就是重点。这就是为什么我否决了你的答案。因为它没有回答这个问题。你的也没有,但是人们在有足够的机会反思和回顾之前都没有投反对票。你为什么认为我的帖子没有回答这个问题?我已经明确指出了OP显示的代码的问题。他使用字段而不是属性,并且他的对象没有无参数构造函数。这就是他问题的根源,也是他在控制器操作中得到NULL的原因。就您的更新而言,它仍然存在问题。见我对你答案的第一句评论。
Request URL:http://localhost:3080/Controller/Action
Request Method:POST
Status Code:200 OK

CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[0].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[1].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[2].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[3].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[4].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[5].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[6].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[7].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[8].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[9].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[10].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[11].IsLicensed:false
    CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[12].IsLicensed:false
    DatabaseName:myDb
@using (Html.BeginForm("Action", FormMethod.Post))
{
    foreach (var option in Model.CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList)
    {
        @Html.CheckBoxFor(o => o.IsLicensed, checkboxHtmlAttributes);
        <label for="@option.LicenseName">@option.LicenseName</label>                                                                                       
        <br/>
    } 
    @Html.HiddenFor(model => model.DatabaseName)
    <input id="submit_licenses" type="submit" style="display:none;" />
}
<input class="licenses" data-val="true" disabled="" id="CompanyOptions_CompanyLicenseOptions_CompanyLicenseOptionsList_0__IsLicensed" name="CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[0].IsLicensed" type="checkbox" value="true" /><input name="CompanyOptions.CompanyLicenseOptions.CompanyLicenseOptionsList[0].IsLicensed" type="hidden" value="false" />
disabled=""
public class CompanyLicenseOptions
{
    public List<CompanyLicenseOption> CompanyLicenseOptionsList { get; set; }
}
public class Company
{
    public string Name { get; set; }
    public string DatabaseName { get; set; }
    public CompanyOptions CompanyOptions { get; set; }
}
public class CompanyOptions
{
    public CompanyLicenseOptions CompanyLicenseOptions { get; set; }
}
public class CompanyLicenseOptions
{
    public List<CompanyLicenseOption> CompanyLicenseOptionsList;
    public CompanyLicenseOptions() 
    {
         CompanyLicenseOptionsList = new List<CompanyLicenseOption>();
    }
}