【问题标题】:Maintain state between Controller calls在 Controller 调用之间保持状态
【发布时间】:2016-05-26 11:12:00
【问题描述】:

我有这个 XML:

<Preferences>
    <Section Name="PREF_SECTION_NAME_1">
    <Preference Name="PREF_NOTIFY_1" Type="radio">    
            <Options>    
                <Option Name="PREF_OPT_YES" Value="true"/>    
                <Option Name="PREF_OPT_NO" Value="false"/>    
            </Options>    
            <Default>true</Default>    
        </Preference>
    </Section>
</Preferences>

我将其序列化为模型并传递给我的视图:

我的观点的一部分

case "radio":
    <b>@Html.Label(Model.Section[i].PreferenceModel[j].Name)</b>

    for (var r = 0; r != Model.Section[i].PreferenceModel[j].Options.Count(); r++)
    {
        if (Model.Section[i].PreferenceModel[j].Default == Model.Section[i].PreferenceModel[j].Options[r].Value)
        {
            @Html.RadioButtonFor(m => m.Section[i].PreferenceModel[j].Name, Model.Section[i].PreferenceModel[j].Options[r].Value, new { @checked = true })
        }
        else
        {
            @Html.RadioButtonFor(m => m.Section[i].PreferenceModel[j].Name, Model.Section[i].PreferenceModel[j].Options[r].Value)
        }
    }

我(作为用户)选择了第二个单选按钮(假)。

然后我在提交按钮上调用我的 Controller 方法并获得这些值:

我需要“默认”来反映用户的选择,在这种情况下应该是“假”。

我已经尝试了所有我能想到的组合,但它仍然总是“空”。

抱歉,我遗漏了一些代码:

@Html.HiddenFor(m => m.Section[i].PreferenceModel[j].Name, "Default")

呈现的 HTML:

<h1><label for="PREF_SECTION_NAME_1">PREF_SECTION_NAME_1</label></h1>
<div class="clear"></div>
<input length="4" id="Section_0__PreferenceModel_0__Type" name="Section[0].PreferenceModel[0].Type" type="hidden" value="radio">
<input length="4" id="Section_0__PreferenceModel_0__Name" name="Section[0].PreferenceModel[0].Name" type="hidden" value="PREF_NOTIFY_1">                            
<b><label for="PREF_NOTIFY_1">PREF_NOTIFY_1</label></b>

<input checked="True" id="Section_0__PreferenceModel_0__Name" name="Section[0].PreferenceModel[0].Name" type="radio" value="true">
<input id="Section_0__PreferenceModel_0__Name" name="Section[0].PreferenceModel[0].Name" type="radio" value="false">
<input length="7" id="Section_0__PreferenceModel_0__Name" name="Section[0].PreferenceModel[0].Name" type="hidden" value="PREF_NOTIFY_1"> 

我的模特:

[XmlRoot("Preferences")]
public class PreferencesModel
{
    /// <summary>
    /// Message to display to user on UI
    /// </summary>
    [XmlIgnore]
    public string MessageToUser { get; set; }
    /// <summary>
    /// Stores Preferences
    /// </summary>
    [XmlElement(ElementName = "Section")]
    public List<Section> Section { get; set; }
}

public class Section
{
    /// <summary>
    /// Name of Section (for Grouping Purposes)
    /// </summary>
    [XmlAttribute("Name")]
    public string Name { get; set; }
    /// <summary>
    /// List of Preferences for this section
    /// </summary>
    [XmlElement("Preference")]
    public List<PreferenceModel> PreferenceModel { get; set; }
}

public class PreferenceModel
{
    /// <summary>
    /// Type of HTML Control ie radio button, textbox
    /// </summary>
    [XmlAttribute("Type")]
    public string Type { get; set; }
    /// <summary>
    /// Name of Preference
    /// </summary>
    [XmlAttribute("Name")]
    public string Name { get; set; }
    /// <summary>
    /// 
    /// </summary>
    //[XmlAttribute("Default")]
    [XmlElement("DefaultValue")]
    public string DefaultValue { get; set; }

    [XmlIgnore]
    public bool CheckBoxValue
    {
        get
        {
            bool flag;
            if (Boolean.TryParse(DefaultValue, out flag))
            {
                return flag;
            }
            else
            {
                return false;
            }
        }
        set
        {
            DefaultValue = value.ToString();
        }
    }

    /// <summary>
     /// 
     /// </summary>
    [XmlElement("Options")]
    public List<Option> Options { get; set; }
}

[XmlType("Option")]
public class Option
{
    /// <summary>
    /// 
    /// </summary>
    [XmlAttribute("Name")]
    public string Name { get; set; }
    /// <summary>
    /// 
    /// </summary>
    [XmlAttribute("Value")]
    public string Value { get; set; }
}

【问题讨论】:

  • 你把 html.hiddenfor 表达式放在表单里面了吗?
  • @StianStandahl 是的。当然。谢谢
  • 您有生成的 html 示例吗?
  • @StianStandahl 给我 1 分钟 :)
  • Html.HiddenFor() 的第二个参数是 htmlAttributes,即 typeof object - 您只使用了 stringstring 只有一个名为 Length 的属性,在您的情况下有 7 个字符,因此它生成了 length="7"

标签: c# asp.net-mvc


【解决方案1】:

您的单选按钮绑定到属性Name,但您需要绑定到属性Default。实际上,DefaultModelBinder 忽略了单选按钮的值,因为您还有一个绑定到属性Name 的隐藏输入(DefaultModelBinder 仅设置第一个并忽略具有相同名称的后续表单值)。

代码中还有一些其他错误,包括在 html 中生成 length="##" 属性,这是由于添加 string 值作为 @Html.HiddenFor() 的第二个参数(用于添加 HtmlAttributes)和设置 @ 987654330@ 属性(你不应该使用它,因为它是你绑定的属性的值,它决定了选择的内容)。

你的代码应该是

case "radio":
    <b>@Model.Section[i].PreferenceModel[j].Name</b>
    for (var r = 0; r != Model.Section[i].PreferenceModel[j].Options.Count; r++)
    {
        <label>
            @Html.RadioButtonFor(m => m.Section[i].PreferenceModel[j].Default, Model.Section[i].PreferenceModel[j].Options[r].Value, new { id = "" })
            <span>@Model.Section[i].PreferenceModel[j].Options[r].Name</span>
        </label>
    }
}

有几点需要注意。您对 @Html.Label() 的使用不合适 - 您没有属性 Name 的关联表单控件。将单选按钮包裹在 &lt;label&gt; 元素中并包含相关文本,以便单击文本切换按钮。从

中删除 id 属性

【讨论】:

  • 感谢您让这看起来如此简单。我原以为 @Html.Label() 不需要关联的表单控件,但 @Html.LabelFor() 需要..?
  • 两者都生成一个&lt;label&gt; 元素,它是一个可访问性元素——单击它会将焦点设置到其关联的表单控件。如果您有一个与属性关联的[Display] 属性,那么您可以使用@Html.DisplayNameFor(m =&gt; m.someProperty) 来输出它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多