如何使用 MVC.Net 将 json 绑定到接口 collection,反之亦然

How to Bind a json to an Interface collection, and vice versa within a model using MVC.Net

更新: 由于答案,我发现旧标题不相关并将其从 'How to Implement Custom JsonConverter that uses JsonConvert' 更改为当前标题。


我的情况很紧,时间也很紧,我必须按照标题说的做...

直到早上我尝试了很多方法,模型没有绑定,方法类似于 MVC 中的 FormCollection returns nulls,等等等等,因为我将接口列表添加到我的一个模型,所以我需要处理它,...早上客户报告错误,他们的系统处于压力之下,所以我忍不住工作直到它修复。

这是我当前的代码:

发生了什么?一旦编写器方法 returns 服务器 returns 500 内部服务器错误...

他们自然会使用序列化程序来执行此操作 object,但我不知道如何使用序列化程序进行此自定义,所以我真的需要调用此接受序列化程序设置的方法。

public class CollectionInterfaceConverterForModels<TInterface> : JsonConverter
{
    private readonly TypeNameSerializationBinder Binder;

    public CollectionInterfaceConverterForModels()
    {
        Binder = new TypeNameSerializationBinder("Cartable.Models.{0}, Cartable");
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IList<TInterface>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        //IList<TInterface> items = serializer.Deserialize<List<TInterface>>(reader).Cast<TInterface>().ToList();
        //return items;
        var json = existingValue.ToString();
        if (json == null)
            json = "";

        return JsonConvert.DeserializeObject<List<TInterface>>(json,
            new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto,
                Binder = Binder
            });
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        //serializer.Serialize(writer, value, typeof(IList<T>));
        string serializeObject = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto,
            Binder = Binder
        });
        writer.WriteRaw(serializeObject);
        writer.Flush();
    }
}

模型样本:

public class IncomingFaxesVM
{
    public long Code { get; set; }
.
.
.

    [JsonConverter(typeof(CollectionInterfaceConverterForModels<IMetadata>))]
    public List<IMetadata> Metadata { get; set; }
}

然而,我无法按照我的要求去做,但我用另一种方式解决了这个问题,

因此,如果您找到答案,我会标记您的答案,否则我会将标题更改为界面绑定,以便其他用户可以轻松找到它,这是我解决问题的答案。

public class CollectionInterfaceConverterForModels<TInterface> : JsonConverter
{
    private readonly TypeNameSerializationBinder Binder;

    public CollectionInterfaceConverterForModels()
    {
        Binder = new TypeNameSerializationBinder("Cartable.Models.{0}, Cartable");
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IList<TInterface>));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var currentBinder = serializer.Binder;
        var currentTypeNameHandling = serializer.TypeNameHandling;

        serializer.TypeNameHandling = TypeNameHandling.Auto;
        serializer.Binder = Binder;

        IList<TInterface> items = serializer.Deserialize<List<TInterface>>(reader).ToList();

        serializer.TypeNameHandling = currentTypeNameHandling;
        serializer.Binder = currentBinder;

        return items;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        //The reason store these, is to leave system unchanged, in case it customized on general section by another programmer
        var currentBinder = serializer.Binder;
        var currentTypeNameHandling = serializer.TypeNameHandling;

        serializer.TypeNameHandling=TypeNameHandling.Auto;
        serializer.Binder = Binder;

        serializer.Serialize(writer, value, typeof(List<TInterface>));

        serializer.TypeNameHandling = currentTypeNameHandling;
        serializer.Binder = currentBinder;
    }
}