【问题标题】:Html.CheckBoxFor TypeConversition ErrorHtml.CheckBoxFor 类型转换错误
【发布时间】: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 值为 falseRequest["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


【解决方案1】:

根据@StephenMuecke,这是默认行为。可以查看详细answer

根据@ataravati,我们应该在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.
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 2018-06-11
    • 2019-01-23
    相关资源
    最近更新 更多