【问题标题】:Mvc binding issue from json to enum (customexception from int to enum)从 json 到枚举的 Mvc 绑定问题(从 int 到枚举的自定义异常)
【发布时间】:2011-06-28 10:00:03
【问题描述】:

我有这个问题:我使用 json 向服务器发送数据。 一切正常,但问题是这样的情况:

public enum SexType
{
  Male : 0,
  Female : 1
}

class People{
  public SexType Sex {get;set;}
}

这为我创建了 json:

{"Sex" : 0}

当我发回服务器时,这会用这个问题填充 ModelStateError: 从类型“System.Int32”到类型“SexType”的参数转换失败,因为没有类型转换器可以在这些类型之间进行转换。

但如果我用 ' 包装值一切正常:

{"Sex" : '0'}

有人有同样的问题吗?

Tnx 为所有人服务!

【问题讨论】:

    标签: json model-view-controller binding


    【解决方案1】:

    是的,我遇到了同样的问题。奇怪的问题是,如果你发回:

    {"Sex" : 'Male'}
    

    它会反序列化没有问题。 为了解决这个问题,我利用此处找到的示例为枚举实现了一个自定义模型绑定器(由于存在一些错误而稍作修改): http://eliasbland.wordpress.com/2009/08/08/enumeration-model-binder-for-asp-net-mvc/

    namespace yournamespace
    {
        /// <summary>
        /// Generic Custom Model Binder used to properly interpret int representation of enum types from JSON deserialization, including default values
        /// </summary>
        /// <typeparam name="T">The enum type to apply this Custom Model Binder to</typeparam>
        public class EnumBinder<T> : IModelBinder
        {
            private T DefaultValue { get; set; }
    
            public EnumBinder(T defaultValue)
            {
                DefaultValue = defaultValue;
            }
    
            #region IModelBinder Members
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                return bindingContext.ValueProvider.GetValue(bindingContext.ModelName) == null ? DefaultValue : GetEnumValue(DefaultValue, bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue);
            }
            #endregion
    
            public static T GetEnumValue<T>(T defaultValue, string value)
            {
                T enumType = defaultValue;
    
                if ((!String.IsNullOrEmpty(value)) && (Contains(typeof(T), value)))
                    enumType = (T)Enum.Parse(typeof(T), value, true);
    
                return enumType;
            }
    
            public static bool Contains(Type enumType, string value)
            {
                return Enum.GetNames(enumType).Contains(value, StringComparer.OrdinalIgnoreCase);
            }
        }
    }
    

    然后在 global.asax.cs 中注册模型绑定器。 在你的情况下,它会是这样的:

    ModelBinders.Binders.Add(typeof(SexType), new EnumBinder<SexType>(SexType.Male));
    

    我不确定是否有更快的方法,但这很好用。

    【讨论】:

      【解决方案2】:

      Model 绑定使用 Enum.Parse() 方法,该方法在解释字符串方面相当聪明,但不会显式地将其他类型强制转换或转换为字符串,即使存在系统级工具可以这样做,即使它们是Enum 中使用的内部存储类型。

      这是正确的行为吗?可以说是这样,因为如果您没有足够的知识将 Enum 值转换为字符串,您可能不会意识到 Enum 值的右侧在 Enum 中也不一定是唯一的。

      出于个人喜好(这也可能是因为我做了太多的统计分析编程)对于性,我通常更喜欢将其定义为一个明确的布尔值,即,而不是区分“男性”的任意值和“女性”我使用了一个名为例如的变量IsFemale 并将其设置为 true 或 false。这与 json 配合得更好,因为它依赖于两种语言共有的原始类型,并且在您想使用它时需要更少的输入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-29
        • 2021-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多