我们发现支持 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)
该操作采用一组参数(一些可选参数)用于 DB 查询,并以 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
它们都是or or 。int?
string
DateTime
DataSourceRequest
中的代码引发了异常System.Web.Mvc.ValueProviderResult.ConvertSimpleType
,它从堆栈跟踪中看起来好像参数的类型错误。
我的阅读表明,如果参数的值为null
or String.Empty
,那么它应该将 a 传递给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 错误,所以我无法想象它仍然是这个问题,但可能有相关的东西吗?Application_Start()
建议的修复是在 Global.asax.cs中添加以下内容:
ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider();
在@mattytommo 的建议下,我们尝试重新排列签名,以便可以为空的参数都排在最后,但这没有区别。