【发布时间】:2015-12-04 15:42:34
【问题描述】:
我有一个视图模型:
public class RegisterModel
{
...
public bool Confirmation{ get; set; }
}
我在视图中使用复选框助手:
@model RegisterModel
......
@Html.CheckBoxFor(m => m.Confirmation)
此复选框 html 助手创建:
<input id="Confirmation" name="Confirmation" value="true" type="checkbox">
<input name="Confirmation" value="false" type="hidden">
在控制器上
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (!ModelState.IsValid)
return View(model);
.....
}
假设某些用户将输入值更改为“xxx”并发布它。因此,模型无效,我们返回视图。之后,Html.CheckBoxFor 给出了这个错误:
从类型'System.String'到类型的参数转换 'System.Boolean' 失败。
内部异常:
System.FormatException: xxx 不是布尔值的有效值
当我们返回视图时:Model.Confirmation 值为 false 但Request["Confirmation"] 值为 'xxx'。
此错误来自ConvertSimpleType 方法上的ValueProviderResult 类。我认为,它尝试将 Request["Confirmation"] 值转换为布尔值并给出错误。
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Conversion failure is not fatal")]
private static object ConvertSimpleType(CultureInfo culture, object value, Type destinationType)
{
.....
TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
bool canConvertFrom = converter.CanConvertFrom(value.GetType());
if (!canConvertFrom)
{
converter = TypeDescriptor.GetConverter(value.GetType());
}
if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
{
// EnumConverter cannot convert integer, so we verify manually
if (destinationType.IsEnum && value is int)
{
return Enum.ToObject(destinationType, (int)value);
}
string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ValueProviderResult_NoConverterExists,
value.GetType().FullName, destinationType.FullName);
throw new InvalidOperationException(message);
}
.....
}
如何修复或避免此错误?
【问题讨论】:
-
这很奇怪。为什么
CheckBoxFor会创建两个名称完全相同的输入? -
@SantiagoHernández - 创建了两个输入。如果未选中复选框,则不会发布。 stackoverflow.com/questions/2860940/…
-
好吧,你不能把
ModelState.IsValue == false的值改成false吗? -
感谢 @ataravati 我将我的 model.isvalid 代码更改为
if (!ModelState.IsValid) { bool confirmation = bool.TryParse(Request["Confirmation"],out confirmation); ModelState.Remove("Confirmation"); request.Confirmation = confirmation; return View(request); }但我不知道为什么助手会尝试从模型之外的请求中获取价值。 -
我的意思是,为了发布除
False之外的值,恶意用户必须操纵隐藏输入的值(例如,使用 fiddler 发布值以尝试并导致您的应用程序失败)。那么为什么不直接将他们重定向到一个错误页面,告诉他们......
标签: c# asp.net-mvc razor html-helper