StringEnumConverter invalid int values

两盒软妹~` 提交于 2019-12-13 14:25:09

问题


I have a simple Controller with a POST method.
My model has a property of type enum.
When I send valid values ,everything works as expected

{  "MyProperty": "Option2"}

or

{  "MyProperty": 2}

If I send an invalid string

{  "MyProperty": "Option15"}

it correctly gets the default value (Option1) but if I send an invalid int ,it keep the invalid value

{  "MyProperty": 15}

Can I avoid that and get the default value or throw an error?

Thanks

public class ValuesController : ApiController
{
    [HttpPost]
    public void Post(MyModel value) {}
}

public class MyModel
{
    [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
    public MyEnum MyProperty { get; set; }
}

public enum MyEnum
{
    Option1 = 0,
    Option2,
    Option3
}

Update
I know I can cast any int to an enum,that's not the problem.
@AakashM's suggestion solves half my problem,I didn't know about AllowIntegerValues

Now I correctly get an error when Posting an invalid int

{  "MyProperty": 15} 

The only problematic case now is when I post a string which is a number (which is strange because when I send an invalid non numeric string it correctly fails)

{  "MyProperty": "15"}

回答1:


I solved my problem by extending StringEnumConverter and using @ AakashM's suggestion

public class OnlyStringEnumConverter : StringEnumConverter
{
    public OnlyStringEnumConverter()
    {
        AllowIntegerValues = false;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (!AllowIntegerValues && reader.TokenType == JsonToken.String)
        {
            string s = reader.Value.ToString().Trim();
            if (!String.IsNullOrEmpty(s))
            {
                if (char.IsDigit(s[0]) || s[0] == '-' || s[0] == '+')
                {
                    string message = String.Format(CultureInfo.InvariantCulture, "Value '{0}' is not allowed for enum '{1}'.", s, objectType.FullName);
                    string formattedMessage = FormatMessage(reader as IJsonLineInfo, reader.Path, message);
                    throw new JsonSerializationException(formattedMessage);
                }
            }
        }
        return base.ReadJson(reader, objectType, existingValue, serializer);
    }

    // Copy of internal method in NewtonSoft.Json.JsonPosition, to get the same formatting as a standard JsonSerializationException
    private static string FormatMessage(IJsonLineInfo lineInfo, string path, string message)
    {
        if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
        {
            message = message.Trim();
            if (!message.EndsWith("."))
            {
                message += ".";
            }
            message += " ";
        }
        message += String.Format(CultureInfo.InvariantCulture, "Path '{0}'", path);
        if (lineInfo != null && lineInfo.HasLineInfo())
        {
            message += String.Format(CultureInfo.InvariantCulture, ", line {0}, position {1}", lineInfo.LineNumber, lineInfo.LinePosition);
        }
        message += ".";
        return message;
    }

}



回答2:


MyEnum _myProperty;
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public MyEnum MyProperty 
{ 
    get
    {
        return _myProperty;
    }
    set
    {
        if (Enum.IsDefined(typeof(MyEnum), value))
            _myProperty = value;
        else
            _myProperty = 0;
    }
}


来源:https://stackoverflow.com/questions/35479669/stringenumconverter-invalid-int-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!