为了账号安全,请及时绑定邮箱和手机立即绑定

模型上的 IDictionary 属性抛出 System.InvalidCastException

模型上的 IDictionary 属性抛出 System.InvalidCastException

C#
慕工程0101907 2023-08-20 10:09:10
我有一个数据库模型,它将设置存储为 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;  }}
查看完整描述

1 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我不能确定,但我猜测客户端正在将枚举作为字符串值发送?


{

"Setting1":true,

"Setting2":false

}

这将失败,因为默认绑定试图将该字符串转换回枚举。如果它传回枚举的整数值而不是字符串,我认为这会起作用。如果您获取字符串值,那么您可能需要创建自定义模型绑定程序。


查看完整回答
反对 回复 2023-08-20
  • 1 回答
  • 0 关注
  • 57 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信