在MVC3項目裡,如果Action的參數中有Enum枚舉作為對象屬性的話,使用POST方法提交過來的JSON數據中的枚舉值卻無法正確被識別對應的枚舉值。
為了說明問題,我使用MVC3項目創建Controller,並且創建如下代碼演示:
- //交通方式枚舉
- public enum TrafficEnum
- {
- Bus = 0,
- Boat = 1,
- Bike = 2,
- }
- public class Person
- {
- public int ID { get; set; }
- public TrafficEnum Traffic { get; set; }
- }
- public class DemoController : Controller
- {
- public ActionResult Index(Person p)
- {
- return View();
- }
- }
網站生成成功之後,就可以使用Fiddler來發送HTTP POST請求了,注意需要的是,要在Request Headers加上請求頭content-type:application/json,這樣才能通知服務器端Request Body裡的內容為JSON格式。
點擊右上角的Execute執行HTTP請求,在程序斷點情況下,查看參數p,屬性ID已經正確的被識別到了值為9999,而枚舉值屬性Traffic卻被錯認為枚舉中的首個值Bus,這俨然是錯誤的,縱使你將Traffic修改成Bike,也就是值等於2,結果也是一樣。
升級MVC4,親測在MVC4項目下,這個問題已經被修復了;
假若因為各種原因,項目不想或者不能升級為MVC4,可以在MVC3項目上做些改動,亦可修復這個問題,
1、在項目中,新建一個類,加入以下代碼,需要引用一下 using System.ComponentModel; using System.Web.Mvc; 命名空間;
- /// <summary>
- /// 處理在MVC3下,提交的JSON枚舉值在Controller不能識別的問題
- /// </summary>
- public class EnumConverterModelBinder : DefaultModelBinder
- {
- protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
- {
- var propertyType = propertyDescriptor.PropertyType;
- if (propertyType.IsEnum)
- {
- var providerValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
- if (null != providerValue)
- {
- var value = providerValue.RawValue;
- if (null != value)
- {
- var valueType = value.GetType();
- if (!valueType.IsEnum)
- {
- return Enum.ToObject(propertyType, value);
- }
- }
- }
- }
- return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
- }
- }
2、在Global.asax的Application_Start方法中,進行EnumConverterModelBinder類的實例化操作:
- protected void Application_Start()
- {
- //處理在MVC3下,提交的JSON枚舉值在Controller不能識別的問題
- ModelBinders.Binders.DefaultBinder = new EnumConverterModelBinder();
- }
進行配置改造之後,我再次生成網站,重新發送HTTP請求看,MVC Action中的參數裡的枚舉就能被正確的識別到了。