MVC 4 控制器操作参数 System.FormatException bug.



我们发现支持KendoUI网格的ajax控制器操作抛出了很多System.FormatException异常,见下文。

当尝试将查询字符串参数从 AJAX 请求绑定到操作参数时,MVC 堆栈会引发异常 - 早在执行操作代码之前。但是,它们不会在每个请求上抛出,相同的 POST 数据有时会导致异常,有时不会导致异常。

System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information. ---> System.Exception: NaN is not a valid value for Int32. ---> System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.ComponentModel.Int32Converter.FromString(String value, NumberFormatInfo formatInfo)
   at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   --- End of inner exception stack trace ---
   at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
   --- End of inner exception stack trace ---
   at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
   at Kendo.Mvc.UI.DataSourceRequestModelBinder.TryGetValue[T](ModelBindingContext bindingContext, String key, T& result)
   at Kendo.Mvc.UI.DataSourceRequestModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)

该操作为数据库查询采用一组参数(其中一些是可选的),并以 JSON 形式返回结果集。它看起来像这样:

public ActionResult List([DataSourceRequest] DataSourceRequest request, int? companyID, int? statusID, int? countryID, int? licenseID, string userID, DateTime fromDate, DateTime toDate)
{
    //Do stuff
}

AJAX 发布值如下所示:

    sort=&page=1&group=&filter=&companyID=&licenseID=&countryID=&statusID=&userID=&fromDate=24%2F12%2F2012&toDate=23%2F01%2F2013

每个参数的值取自页面上的一组下拉列表。仅当在其中一个下拉列表中设置了"all"选项时,才会发生异常,其中没有设置值。

<select name="CompanyID"><option value="">All Companies</option>
    <option value="1">Comapny 1</option>
    <option value="2">Company 2</option>
</select>
<!-- ... snip ... -->
令人

困惑的是,所讨论的参数都不是int类型,它们都是int?stringDateTimeDataSourceRequest

异常是由 System.Web.Mvc.ValueProviderResult.ConvertSimpleType 中的代码引发的,从堆栈跟踪来看,它似乎弄错了参数的类型。

我的阅读表明,在参数值为 nullString.Empty 的情况下,它应该将null传递给控制器操作。我在这里找到的来源(第 54 行)似乎证实了这一点:

// if this is a user-input value but the user didn't type anything, return no value
string valueAsString = value as string;
if (valueAsString != null && valueAsString.Trim().Length == 0)
{
    return null;
}

我发现了对一个旧的 MVC-3 错误的引用,该错误导致内部信息缓存不正确并导致此异常。这里有一个关于它的讨论,它被确认为 MVC3 RC2 错误,所以我无法想象它仍然是这个问题,但可能有什么相关的东西吗?建议的修复方法是将以下内容添加到 Global.asax.cs 中的Application_Start()

ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider();

在@mattytommo的建议下,我们尝试重新排列签名,使可为空的参数都排在最后,但这没有区别。

这与我们添加的可选参数无关,这取决于 KendoUI 脚本。

Kendo javascript添加了一堆参数(组,排序,页面),这些参数映射到DataSourceRequest对象上。

此对象的Page属性定义为

public int Page { get; set; }`

但是在我们应用的过滤器没有返回任何结果(空网格)的情况下,javascript 正在page=NaN设置,因此出现错误:

System.Exception: NaN is not a valid value for Int32

相关内容

最新更新