从 json 到 enum 的 Mvc 绑定问题(从 int 到 enum 的自定义异常)

发布于 2024-10-17 19:46:30 字数 438 浏览 2 评论 0原文

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

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

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

创建 json:

{"Sex" : 0}

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

但是,如果我用 ' 包装该值,则一切正常:

{"Sex" : '0'}

有人有同样的问题吗?

为所有人服务!

i have this problem: i use the json to send data to server.
All works fine but the problem is a situation like:

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

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

That create me the json:

{"Sex" : 0}

When i send back to server, this fill the ModelStateError with this issue:
The parameter conversion from type 'System.Int32' to type 'SexType' failed because no type converter can convert between these types.

But if i wrap the value with ' all work well:

{"Sex" : '0'}

Anyone have the same problem?

Tnx for all!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别闹i 2024-10-24 19:46:30

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

{"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));

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

Yes, I got the same problem. The weird problem is that if you sent back:

{"Sex" : 'Male'}

it would deserialize no problem.
To solve the problem, I implemented a custom model binder for enums, leveraging the example found here (slightly modified as there were some errors):
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);
        }
    }
}

and then registering the model binder in global.asax.cs.
In your case it would be something like:

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

I am not sure if there is a quicker way, but this works great.

幸福不弃 2024-10-24 19:46:30

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

这是正确的行为吗?可以说是这样,因为如果您不知道如何将枚举值转换为字符串,您可能不知道枚举值的右侧在枚举中也不一定是唯一的。

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

The Model binding uses the Enum.Parse() method, which is fairly smart about interpreting strings but does NOT explicitly cast or convert other types into strings, even if system-level facilities exist to do so and even if they're the internal storage type used within the Enum.

Is this the right behavior? Arguably so, since if you don't know enough to convert your Enum values to strings you might not be aware that the right-hand side of the Enum values are not necessarily unique within the Enum, either.

As a matter of personal taste (and this is probably also because I do way too much statistical analysis programming) for sex I generally prefer to define it as a clear boolean value, i.e. instead of differentiating between arbitrary values for 'Male' and 'Female' I use a variable called e.g. IsFemale and set it to true or false. This plays more nicely with json, since it relies on primitive types common to both languages, and requires less typing when you want to use it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文