类型转换错误的Html.CheckBox
本文关键字:CheckBox Html 错误 类型转换 | 更新日期: 2023-09-27 18:25:37
我有一个视图模型:
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"并发布它。因此,Model无效,我们返回视图。之后,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);
}
.....
}
如何修复或避免此错误?
根据@StephenMuecke的说法,这是默认行为。您可以查看详细答案
根据@atravati的说法,我们应该在model.IsValid==false
上处理这个问题。如果模型无效,我们将删除复选框的值并分配新的值。因此,当我们返回视图时,不会出现任何错误。
if (!ModelState.IsValid)
{
bool confirmation;
bool.TryParse(Request["Confirmation"],out confirmation);
ModelState.Remove("Confirmation");
request.Confirmation = confirmation;
return View(request);
}
根据@StephenMuecke的说法,如果复选框输入值不是布尔值,那么用户肯定是恶意的。因此,我们将用户重定向到另一个具有跟踪/阻止ip算法的动作,并返回404作为视图。
if (!ModelState.IsValid)
{
bool confirmation;
if (bool.TryParse(Request["Confirmation"], out confirmation))
return View(request);
return RedirectToAction("Http404", "Errors"); //This not just redirecting 404, it has also tracking/blocking ip algorithm.
}