MVC 4 Controller动作参数System.FormatException错误

时间:2013-01-23 14:51:33

标签: exception asp.net-mvc-4 kendo-grid

我们发现支持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

每个参数的值取自页面上的一组下拉列表。仅当在其中一个下拉列表中设置“全部”选项时,才会发生例外情况,其中没有设置值。

<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传递给控制器​​操作。我发现here(第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错误,该错误导致内部信息的错误缓存并导致此异常。有一个讨论它here,它被确认为MVC3 RC2错误,所以我无法想象它仍然是这个问题,但可能有相关的东西?建议的修复方法是将以下内容添加到Global.asax.cs中的Application_Start()

ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider();

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

1 个答案:

答案 0 :(得分:0)

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

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

此对象的Page属性定义为

public int Page { get; set; }`

但是在我们应用的过滤器返回 no results (空网格)的情况下,javascript正在设置page=NaN,因此错误:

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