如何使用 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;
}
}
更新: 由于答案,我发现旧标题不相关并将其从 '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;
}
}