Web API ModelBinders - how to bind one property of your object differently

旧街凉风 提交于 2019-11-30 20:29:44

In Web API you have to distinguish three concepts - ModelBinding, Formatters and ParameterBinding. That is quite confusing to people moving from/used to MVC, where we only talk about ModelBinding.

ModelBinding, contrary to MVC, is responsible only for pulling data out of URI. Formatters deal with reading the body, and ParameterBinding (HttpParameterBinding) encompasses both of the former concepts.

ParameterBinding is really only useful when you want to revolutionize the whole mechanism (i.e. allow two objects to be bound from body, implement MVC-style binding and so on) - for simpler tasks modifying binders (for URI specific data) or formatters (for body data) is almost always more than enough.

Anyway, to the point - what you want to achieve can very easily be done with a custom JSON.NET converter (JSON.NET is the default serialization library behind Web API JSON formatting engine).

All you need to do is:

public class Param
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonConverter(typeof(CustomArrayConverter))]
    public string Choices { get; set; }
}

And then add the converter:

internal class CustomArrayConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                    JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        return JsonConvert.SerializeObject(array);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, JArray.Parse(value as string));
    }
}

In this case we are telling JSON.NET in the converter to store Choices as string (in the read method), and when you return the Param object with the Choices property to the client (in the write method) we take the string and serialize to an array so that the output JSON looks identical to the input one.

You can test it now like this:

    public Param PostParam(Param param)
    {
        return param;
    }

And verify that the data coming in is like you wished, and the data coming out is identical to the original JSON.

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