我有一個數據庫模型,它將設置存儲為 32 位整數上的位.HasFlag。前端使用 AngularJs (1),遺憾的是它不允許在表達式中進行按位運算。因此,我創建了一個擴展方法,用于從枚舉轉換為每個標志的字典以及它是否打開:public static IDictionary<TEnum, bool> GetAllFlags<TEnum>(this TEnum obj) where TEnum: Enum{ return Enum.GetValues(typeof(TEnum)) .Cast<TEnum>() .ToDictionary(flag => flag, flag => obj.HasFlag(flag));}我還創建了一個擴展方法來設置值,但它依賴于其他擴展方法,并且不會被調用(如下所述),因此為了簡潔起見,我將省略它們。這是正在使用的枚舉的示例(請注意,它的類型默認為int并且只有很少的選項,但它確實定義了一個0奇怪的類型)public enum Settings{ None = 0, Setting1 = 1, Setting2 = 2, Setting3 = 4,}所有這些都作為對象的屬性公開,如下所示// SettingsFlags comes from another partial and is a Settings enum persisted to the database as an `INT`public parital class Options{ IDictionary<Settings, bool> Flags { get { return SettingsFlags.GetAllFlags(); } set { SettingsFlags.SetAllFlags(value); } // this never gets called }}JSON當為客戶端序列化時,這非常有效。但是,當在請求中收到它時,它會拋出以下異常:System.InvalidCastException: Specified cast is not valid. at System.Web.Mvc.DefaultModelBinder.CollectionHelpers.ReplaceDictionaryImpl[TKey,TValue](IDictionary`2 dictionary, IEnumerable`1 newContents)當進入調試器時,該get塊被調用并返回預期的字典。之后,調試器中無需執行任何其他步驟即可引發錯誤。以下是端點的示例(不符合 REST 標準):public JsonResult UpdateSingleItem(Options options, ...){ // breakpoint here is never called. ....}`使用ReSharperwithDotPeak檢查代碼為我提供了引發錯誤的方法的以下信息:// System.Web.Mvc.DefaultModelBuilder.CollectionHelpersprivate static void ReplaceDictionaryImpl<TKey, TValue>( IDictionary<TKey, TValue> dictionary, IEnumerable<KeyValuePair<object, object>> newContents){ dictionary.Clear(); foreach (KeyValuePair<object, object> newContent in newContents) { TKey key = (TKey) newContent.Key; TValue obj = newContent.Value is TValue ? (TValue) newContent.Value : default (TValue); dictionary[key] = obj; }}
模型上的 IDictionary 屬性拋出 System.InvalidCastException
慕工程0101907
2023-08-20 10:09:10