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
各パラメーターの値は、ページ上の一連のドロップダウンから取得されます。値が設定されていないこれらのドロップダウンのいずれかで「all」オプションが設定されている場合にのみ、例外が発生します。
<select name="CompanyID"><option value="">All Companies</option>
<option value="1">Comapny 1</option>
<option value="2">Company 2</option>
</select>
<!-- ... snip ... -->
紛らわしいのは、問題のパラメータの型が ではなく、int
すべてorであるということです。int?
string
DateTime
DataSourceRequest
のコードで例外が発生していSystem.Web.Mvc.ValueProviderResult.ConvertSimpleType
ます。スタック トレースから、パラメータの型が間違っているように見えます。
null
私の読書は、パラメーターの値がまたはの場合、コントローラーアクションに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 の提案で、null 許容パラメーターがすべて最後になるように署名を再配置しようとしましたが、これは違いはありません。