为什么我的 MVC 模型绑定在此枚举的回发中失败?
Why is my MVC model binding failing on postback for this enum?
我有一个模型 class,其值为 SomeEnum
public class SomeModel
{
public SomeEnum MyChoice { get; set; }
}
public enum SomeEnum
{
OptionOne, OptionTwo, OptionThree
}
我有一个为枚举呈现一组单选按钮的编辑器模板:
@model Enum
@{
var enumType = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType)
?? ViewData.ModelMetadata.ModelType;
var items = Model.SelectListItems(enumType);
}
<div class="form-group">
@foreach (var item in items)
{
var id = Guid.NewGuid();
<div class="form-check">
// also tried ViewData.ModelMetadata.PropertyName below
@Html.RadioButton(ViewData.TemplateInfo.HtmlFieldPrefix,
item.Value,
item.Value.Equals(Model.ToString()),
new {id, @class = "form-check-input"})
@Html.Label(item.Text, new {@for = @id, @class = "form-check-label"})
</div>
}
@Html.ValidationMessageFor(m => m)
</div>
呈现为
<div class="form-group">
<div class="form-check">
<input id="guid1" name="MyChoice.MyChoice" checked="checked"
class="form-check-input" type="radio" value="OptionOne">
<label for="guid1" class="form-check-label">Option One</label>
</div>
<div class="form-check">
<input id="guid2" name="MyChoice.MyChoice"
class="form-check-input" type="radio" value="OptionTwo">
<label for="guid2" class="form-check-label">Option Two</label>
</div>
<div class="form-check">
<input id="guid3" name="MyChoice.MyChoice"
class="form-check-input" type="radio" value="OptionThree">
<label for="guid3" class="form-check-label">Option Three</label>
</div>
<span class="field-validation-valid"
data-valmsg-for="MyChoice" data-valmsg-replace="true"></span>
</div>
我认为问题在于 name
属性总是将 "doubled up" 呈现为 MyChoice.MyChoice
与 MyChoice
(使用 ViewData.ModelMetadata.PropertyName
时相同),但我无法确定原因。
将枚举转换为字符串:
public class SomeModel
{
private SomeEnum _MyChoice { get; set; }
public string MyChoice
{
get { return _MyChoice.ToString(); }
set { _MyChoice = (SomeEnum)Enum.Parse(_MyChoice.GetType(), value); }
}
}
public enum SomeEnum
{
OptionOne, OptionTwo, OptionThree
}
原来解决方案是替换
@Html.RadioButton(ViewData.TemplateInfo.HtmlFieldPrefix,
item.Value,
item.Value.Equals(Model.ToString()),
new {id, @class = "form-check-input"})
与:
@Html.RadioButton("", item.Value,
item.Value.Equals(Model.ToString()),
new {id, @class = "form-check-input"})
没错:替换 name
属性(描述为“表单字段的名称和用于查找值的 ViewDataDictionary 键”)。使用 空字符串 会导致 html 中的 name
属性正确呈现,例如:
<input id="guid1" class="form-check-input" name="MyChoice" type="radio" value="OptionOne">
... 并且模型绑定按预期工作,在回发时将所选值作为枚举 传递回模型中的表单 。如果这在某个地方有记录就更好了,或者更好,不是这样,但是你去吧。
我有一个模型 class,其值为 SomeEnum
public class SomeModel
{
public SomeEnum MyChoice { get; set; }
}
public enum SomeEnum
{
OptionOne, OptionTwo, OptionThree
}
我有一个为枚举呈现一组单选按钮的编辑器模板:
@model Enum
@{
var enumType = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType)
?? ViewData.ModelMetadata.ModelType;
var items = Model.SelectListItems(enumType);
}
<div class="form-group">
@foreach (var item in items)
{
var id = Guid.NewGuid();
<div class="form-check">
// also tried ViewData.ModelMetadata.PropertyName below
@Html.RadioButton(ViewData.TemplateInfo.HtmlFieldPrefix,
item.Value,
item.Value.Equals(Model.ToString()),
new {id, @class = "form-check-input"})
@Html.Label(item.Text, new {@for = @id, @class = "form-check-label"})
</div>
}
@Html.ValidationMessageFor(m => m)
</div>
呈现为
<div class="form-group">
<div class="form-check">
<input id="guid1" name="MyChoice.MyChoice" checked="checked"
class="form-check-input" type="radio" value="OptionOne">
<label for="guid1" class="form-check-label">Option One</label>
</div>
<div class="form-check">
<input id="guid2" name="MyChoice.MyChoice"
class="form-check-input" type="radio" value="OptionTwo">
<label for="guid2" class="form-check-label">Option Two</label>
</div>
<div class="form-check">
<input id="guid3" name="MyChoice.MyChoice"
class="form-check-input" type="radio" value="OptionThree">
<label for="guid3" class="form-check-label">Option Three</label>
</div>
<span class="field-validation-valid"
data-valmsg-for="MyChoice" data-valmsg-replace="true"></span>
</div>
我认为问题在于 name
属性总是将 "doubled up" 呈现为 MyChoice.MyChoice
与 MyChoice
(使用 ViewData.ModelMetadata.PropertyName
时相同),但我无法确定原因。
将枚举转换为字符串:
public class SomeModel
{
private SomeEnum _MyChoice { get; set; }
public string MyChoice
{
get { return _MyChoice.ToString(); }
set { _MyChoice = (SomeEnum)Enum.Parse(_MyChoice.GetType(), value); }
}
}
public enum SomeEnum
{
OptionOne, OptionTwo, OptionThree
}
原来解决方案是替换
@Html.RadioButton(ViewData.TemplateInfo.HtmlFieldPrefix,
item.Value,
item.Value.Equals(Model.ToString()),
new {id, @class = "form-check-input"})
与:
@Html.RadioButton("", item.Value,
item.Value.Equals(Model.ToString()),
new {id, @class = "form-check-input"})
没错:替换 name
属性(描述为“表单字段的名称和用于查找值的 ViewDataDictionary 键”)。使用 空字符串 会导致 html 中的 name
属性正确呈现,例如:
<input id="guid1" class="form-check-input" name="MyChoice" type="radio" value="OptionOne">
... 并且模型绑定按预期工作,在回发时将所选值作为枚举 传递回模型中的表单 。如果这在某个地方有记录就更好了,或者更好,不是这样,但是你去吧。