国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

MVC3不能正確識別JSON中的Enum枚舉值

開發(fā) 后端
在MVC3項目里,如果Action的參數中有Enum枚舉作為對象屬性的話,使用POST方法提交過來的JSON數據中的枚舉值卻無法正確被識別對應的枚舉值。

一、背景

在MVC3項目里,如果Action的參數中有Enum枚舉作為對象屬性的話,使用POST方法提交過來的JSON數據中的枚舉值卻無法正確被識別對應的枚舉值。

二、Demo演示

為了說明問題,我使用MVC3項目創(chuàng)建Controller,并且創(chuàng)建如下代碼演示:

  1. //交通方式枚舉  
  2.     public enum TrafficEnum  
  3.     {  
  4.         Bus = 0,  
  5.         Boat = 1,  
  6.         Bike = 2,  
  7.     }  
  8.     public class Person  
  9.     {  
  10.         public int ID { get; set; }  
  11.         public TrafficEnum Traffic { get; set; }  
  12.     }  
  13.  
  14.     public class DemoController : Controller  
  15.     {  
  16.         public ActionResult Index(Person p)  
  17.         {  
  18.             return View();  
  19.         }  
  20.     } 

網站生成成功之后,就可以使用Fiddler來發(fā)送HTTP POST請求了,注意需要的是,要在Request Headers加上請求頭content-type:application/json,這樣才能通知服務器端Request Body里的內容為JSON格式。

      點擊右上角的Execute執(zhí)行HTTP請求,在程序斷點情況下,查看參數p,屬性ID已經正確的被識別到了值為9999,而枚舉值屬性Traffic卻被錯認為枚舉中的首個值Bus,這儼然是錯誤的,縱使你將Traffic修改成Bike,也就是值等于2,結果也是一樣。

三、解決方法

方法一:

升級MVC4,親測在MVC4項目下,這個問題已經被修復了;

方法二:

假若因為各種原因,項目不想或者不能升級為MVC4,可以在MVC3項目上做些改動,亦可修復這個問題,

1、在項目中,新建一個類,加入以下代碼,需要引用一下 using System.ComponentModel;  using System.Web.Mvc; 命名空間;

  1. /// <summary>  
  2.     /// 處理在MVC3下,提交的JSON枚舉值在Controller不能識別的問題  
  3.     /// </summary>  
  4.     public class EnumConverterModelBinder : DefaultModelBinder  
  5.     {  
  6.         protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)  
  7.         {  
  8.             var propertyType = propertyDescriptor.PropertyType;  
  9.             if (propertyType.IsEnum)  
  10.             {  
  11.                 var providerValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);  
  12.                 if (null != providerValue)  
  13.                 {  
  14.                     var value = providerValue.RawValue;  
  15.                     if (null != value)  
  16.                     {  
  17.                         var valueType = value.GetType();  
  18.                         if (!valueType.IsEnum)  
  19.                         {  
  20.                             return Enum.ToObject(propertyType, value);  
  21.                         }  
  22.                     }  
  23.                 }  
  24.             }  
  25.             return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);  
  26.         }  
  27.     } 

2、在Global.asax的Application_Start方法中,進行EnumConverterModelBinder類的實例化操作:

  1. protected void Application_Start()  
  2.  {  
  3.      //處理在MVC3下,提交的JSON枚舉值在Controller不能識別的問題  
  4.      ModelBinders.Binders.DefaultBinder = new EnumConverterModelBinder();  
  5.  } 

進行配置改造之后,我再次生成網站,重新發(fā)送HTTP請求看,MVC Action中的參數里的枚舉就能被正確的識別到了。

#p#

四、研究

我覺得這應該是mvc3里面一個小小的缺陷吧,隨著mvc的升級,這已經在新版本里被完善修復了,可還用著mvc3的人如果在項目中遇到這個問題,可以研究一下。

遇到一個問題,去百度谷歌找解決方案是可以,但是復制粘貼完代碼之后,最好問下自己,為什么這樣可以解決問題。

從現(xiàn)象和解決代碼中猜想,應該是在MVC生命周期中的Model Binders 這一環(huán)節(jié)出了問題。

因為MVC已經開源了,所以我嘗試著調試源碼,首先下載MVC3的源碼,其他項目可以移除,只保留紅色框中的項目即可,然后新建一個MVC3測試項目,并且將此測試項目的system.web.mvc引用移除,轉而引用本解決方案中的system.web.mvc 項目,這樣子,我們才可以對MVC源碼進行調試操作。

搜回來的代碼中可知,我們自定義的類繼承DefaultModelBinder父類,并且重寫了GetPropertyValue方法,那我們就從這點開始,在MVC3源碼中的System.Web.MVC項目中找到該類,在此方法上插入斷點。

F5調試程序,發(fā)送一個POST請求。

其實BindProperty方法是會被多次執(zhí)行的,BindProperties方法會對請求的實體類的屬性進行遍歷,每一個屬性都要經過BindProperty方法的處理;

現(xiàn)在已經截獲到第一個屬性ID了。

緊接著,程序進入propertyBinder.BindModel 方法。

只貼部分關鍵代碼了,通過bindingContextValueProvider 獲得屬性的相關信息,如果不等于null的話,轉到執(zhí)行BindSimpleModel 方法。

#p#

BindSimpleModel方法里,首先通過Type.IsInstanceOfType方法判斷確定指定的對象是否是當前 Type 的實例,如果是,則直接返回rawValue,這里的屬性類型是Int32類型,返回True符合條件,所以直接把rawValue給返回去了。

第一個Int32類型屬性的部分關鍵代碼執(zhí)行到這里就已經確認到值了,接下來,我們看出了問題的Enum枚舉類型屬性。

 循環(huán)來到了第二個屬性了,這時我留意到有個Model屬性,對比Int32類型執(zhí)行的時候,這個屬性當時為0,而此時則為Bus,可見這是一個默認值,指定枚舉中值為0的那個類型(即使你不為枚舉顯式指定值),同樣的,經過BindModel方法來到了BindSimpleModel方法。

此時,對比Int32類型的屬性ID,這次ModelType.IsInstanceOfType(valueProvideResult.RawValue)False,并且接下來不是string類型就執(zhí)行以下的判斷,也不是數組類型,所以,來到了最后一個,根據綠色的注釋可以看出,這應該是一個判斷是否collection集合類型的方法,Enum都不是,所以,返回了Null

這時,Type collectionType變量為Null,執(zhí)行最后一個case 3

ConvertProviderResult方法里,也進行了一系列的類型判斷轉換,目的就是將JSON中的數字類型轉換成枚舉值,但是執(zhí)行過程中拋出異常了,原因是

No type converter can convert between these types ” 也就是說,在MVC3的機制中,并沒有相應的type converter來處理數值與枚舉的對應。

經過以上這些處理方法,都沒完成把對應的值確認下來,怎么給原來的BindProperty 老大方法交差呢,所以,小的只好將Value=Null 和 modelState.Errors 模型錯誤狀態(tài)信息如實帶回去了,讓老大決定怎么做,老大后面處理這里有點繞,但是我看源碼估計也是拿默認值來充當Value了,所以就造成了JSON傳過來的值與對應枚舉的值不對應的情況,無論傳什么值,結果都是第一個枚舉的值。

 五、總結

這篇文章只是我在工作上遇到的一個小問題,然后有點小興趣就從源碼的角度上來研究和分析,缺乏理論的依據,因為之前沒有很深入的去研究MVC的底層運行機制與生命周期,所以這方面還需要得加強學習一下,如果你也有興趣,可以下載我修改好的源碼來分析一下,甚至可以下載MVC4的源碼來進行對比。

責任編輯:林師授 來源: 博客園
相關推薦

2012-07-11 23:32:33

MVC3項目

2012-06-26 09:37:54

Web

2012-06-23 20:24:33

Web

2015-06-23 16:42:21

2012-08-27 10:11:43

ASP.NET

2012-07-16 13:02:01

2022-06-27 10:26:37

枚舉Java

2009-04-09 15:40:01

JSONJavaScript枚舉

2010-02-03 10:05:48

C++ enum枚舉

2012-03-13 09:11:46

Web

2011-04-18 09:35:59

ASP.NET MVC

2021-10-26 15:36:17

C++枚舉值類型

2010-05-26 08:56:42

MySQL服務不能啟動

2009-12-04 14:09:52

PHP JSON應用

2010-12-07 09:38:15

ASP.NET MVC

2010-10-20 09:05:16

ASP.NET MVC

2011-04-14 09:19:22

ASP.NET MVC

2009-12-04 18:00:46

PHP開發(fā)MVC模型

2010-10-14 09:05:36

ASP.NET MVC

2010-03-02 14:12:30

WCF枚舉類型
點贊
收藏

51CTO技術棧公眾號

久久亚洲成人精品| 国产精品亚洲一区二区三区在线观看| 激情视频免费网站| 亚洲综合免费观看高清完整版 | 免费h片在线观看| 欧美不卡在线视频| 日韩成人av在线资源| 亚洲国产一区自拍| 日韩高清成人在线| 日韩欧美激情一区二区| 日本a级不卡| 国产免费xxx| 日韩激情av在线| 日本中文字幕高清| 欧美mv日韩mv国产网站| 欧美日韩中文一区二区| 久久www视频| 看国产成人h片视频| 五月伊人六月| 欧美成年人视频网站| 久久国产88| 日本精品一区二区三区高清 久久| 香蕉国产精品| 成人福利视频网| 福利视频网站一区二区三区| av在线免费观看国产| 色94色欧美sute亚洲13| 中文无码日韩欧| av磁力番号网| 制服丝袜亚洲精品中文字幕| 国产日产一区| 91在线观看免费高清| 成人免费va视频| 日韩中文字幕在线视频观看| 欧美精品日韩一区| 成年人网站在线| 日韩成人免费视频| 欧美激情无毛| 97中文字幕| 欧美成人午夜激情| 国产在线一区观看| 欧美日韩经典丝袜| 精品一区二区日本| 色系网站成人免费| 四虎影院观看视频在线观看| 国产一区视频在线播放| 亚洲人成免费网站| 老司机精品福利在线观看| 亚洲午夜精品在线| 欧美日韩直播| 国产性生交xxxxx免费| 亚洲视频一区二区三区| 日韩欧美激情| 欧美专区第一页| 国产婷婷色一区二区三区四区| 国产91福利| 久久亚洲精品成人| av一区二区不卡| 婷婷六月天在线| 久久色免费在线视频| www.亚洲激情.com| 黄色成人在线视频| 91精品国产乱码久久久久久久久| 精品一区av| 国产福利在线免费| 色哟哟欧美精品| 第一会所sis001亚洲| 久久久亚洲精华液精华液精华液 | 久久精品福利视频| 99久久久无码国产精品| 亚洲一区导航| 最近中文字幕一区二区| 97色在线观看免费视频| 亚洲国产精品日韩专区av有中文 | 免费看污黄网站| 性欧美xxxx交| 一区二区三区四区在线免费观看| 在线看黄色av| 在线a欧美视频| 99视频精品在线| 日韩久久99| 男女羞羞视频网站| 成人网在线视频| 欧美一区二区三区在线看| 亚洲啊v在线免费视频| 成人欧美在线视频| 日韩欧美亚洲综合| 韩日一区二区| 国产又大又黄又粗的视频| 国内偷自视频区视频综合| 亚洲精品视频免费观看| 91色在线看| 日韩一二区视频| 久久国产加勒比精品无码| 亚洲三级免费观看| 欧美日韩美女| 69堂成人精品视频免费| 91福利在线播放| 日本最新不卡在线| 小香蕉视频在线| 国内一区在线| 亚洲偷欧美偷国内偷| 亚洲h色精品| 免费av网站在线看| 国产成人avxxxxx在线看| 精品久久久久久久久国产字幕| 国内精品久久久久久久影视麻豆| 天使と恶魔の榨精在线播放| 男人插女人视频在线观看| 91国偷自产一区二区三区的观看方式| 欧美日韩在线视频一区| 日韩福利电影在线观看| 欧美日本三级| 国产视频网址在线| 霍思燕三级露全乳照| 国产精品欧美风情| 精品va天堂亚洲国产| 国产精品人妖ts系列视频| 欧美欧美全黄| 日韩中文影院| 亚洲夫妻av| 欧美中文字幕在线观看视频| 国产精品日韩欧美大师| 亚洲精品成a人在线观看| 亚洲人午夜精品天堂一二香蕉| 亚洲视频大全| 嫩草精品影院| 9色porny| 91免费国产网站| 中文字幕精品一区久久久久| 欧美日韩日本国产| 香港欧美日韩三级黄色一级电影网站| 国内激情视频在线观看| jlzzjlzz欧美| 天天做天天爱天天高潮| 日韩视频免费观看高清在线视频| av成人免费在线观看| 韩国一区二区三区在线观看| 欧洲亚洲妇女av| 免费看欧美一级片| 资源视频在线播放免费| 五月综合激情| 日本精品裸体写真集在线观看| 欧美12一14sex性hd| 黄色一级片在线看| 精品国产乱码一区二区三区四区 | 在线观看亚洲精品福利片| 亚洲激情中文| 在线视频国内自拍亚洲视频| 亚洲精品在线不卡| 亚洲第一偷拍| 国产美女视频一区二区 | 一级片在线视频| 欧美亚洲另类色图| 亚洲免费久久| 成人在线免费网站| 国产成人小视频在线观看| 久久精品视频中文字幕| 精品国产乱码久久久久久蜜臀| 欧美日韩另类字幕中文| 久久精品免视看| 精品亚洲成a人| 夜夜嗨一区二区| 欧美hd在线| 妖精一区二区三区精品视频| 祥仔av免费一区二区三区四区| a级影片在线| av在线资源网| 伪装者在线观看完整版免费| 黄色福利视频网站| 日韩中文字幕a| 国产精品97在线| 亚洲性线免费观看视频成熟| 欧美日韩在线播放三区| 久久亚洲视频| 中文字幕一区二区三区久久网站 | 亚洲人和日本人hd| 日韩一区不卡| 涩爱av在线播放一区二区| 亚洲成人a**址| 久久精品aaaaaa毛片| 99热在线国产| 99久久99| 成人国产在线视频| 国产精品爽爽爽爽爽爽在线观看| 欧美一级大片在线观看| 91av免费观看91av精品在线| 97香蕉超级碰碰久久免费软件| 久久男人资源视频| 97婷婷大伊香蕉精品视频| 性色av香蕉一区二区| 97久久超碰福利国产精品…| 欧美一级大胆视频| 国产精品视频免费在线| 91网在线免费观看| 精品久久久久久亚洲| 性欧美大战久久久久久久免费观看| 在线视频不卡一区二区| avav在线播放| 91黄色小网站|