我正在尝试建立一个读取器,它将从各种网站中获取JSON对象(想想信息抓取)并将它们转换为C#对象.我目前正在使用JSON.NET进行反序列化过程.我遇到的问题是它不知道如何处理类中的接口级属性.所以有些本质:
public IThingy Thing
Run Code Online (Sandbox Code Playgroud)
会产生错误:
无法创建IThingy类型的实例.Type是接口或抽象类,无法实例化.
让它成为ITINGy而不是Thingy是相对重要的,因为我正在处理的代码被认为是敏感的,单元测试非常重要.对于像Thingy这样的完全成熟的对象,不可能对原子测试脚本的对象进行模拟.它们必须是一个接口.
我一直在研究JSON.NET的文档已有一段时间了,我在这个网站上找到的与此相关的问题都来自一年多以前.有帮助吗?
此外,如果重要,我的应用程序是用.NET 4.0编写的.
鉴于此JSON:
[
{
"$id": "1",
"$type": "MyAssembly.ClassA, MyAssembly",
"Email": "me@here.com",
},
{
"$id": "2",
"$type": "MyAssembly.ClassB, MyAssembly",
"Email": "me@here.com",
}
]
Run Code Online (Sandbox Code Playgroud)
和这些类:
public abstract class BaseClass
{
public string Email;
}
public class ClassA : BaseClass
{
}
public class ClassB : BaseClass
{
}
Run Code Online (Sandbox Code Playgroud)
如何将JSON反序列化为:
IEnumerable<BaseClass> deserialized;
Run Code Online (Sandbox Code Playgroud)
我不能使用,JsonConvert.Deserialize<IEnumerable<BaseClass>>()因为它抱怨BaseClass是抽象的.
我正在调用我的WebAPI的方法,发送一个我希望与模型匹配(或绑定)的json.
在控制器中我有一个方法,如:
public Result Post([ModelBinder(typeof(CustomModelBinder))]MyClass model);
Run Code Online (Sandbox Code Playgroud)
'MyClass',作为参数给出的是一个抽象类.我想这样,根据传递的json的类型,实例化正确的继承类.
为了实现它,我正在尝试实现自定义绑定器.问题是(我不知道它是否非常基本,但我找不到任何东西)我不知道如何检索请求中的原始Json(或更好的,某种序列化).
我知道了:
但是所有方法都暴露为异步.我不知道这适合将生成模型传递给控制器方法...
非常感谢!
该项目是Asp.Net Web API Web服务.
我有一个类型层次结构,我需要能够序列化到JSON和从JSON序列化,所以我从这个SO中获取代码:如何在JSON.NET中实现自定义JsonConverter来反序列化基类对象的列表?,并将转换器应用于我的层次结构的基类; 像这样的东西(这里有伪代码隐藏无关紧要):
[JsonConverter(typeof(TheConverter))]
public class BaseType
{
// note the base of this type here is from the linked SO above
private class TheConverter : JsonCreationConverter<BaseType>
{
protected override BaseType Create(Type objectType, JObject jObject)
{
Type actualType = GetTypeFromjObject(jObject); /*method elided*/
return (BaseType)Activator.CreateInstance(actualType);
}
}
}
public class RootType
{
public BaseType BaseTypeMember { get; set; }
}
public class DerivedType : BaseType
{
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我反序列化RootType实例,其BaseTypeMember等于实例DerivedType,然后将它反序列化回到该类型的实例.
对于记录,这些JSON对象包含一个'$type' …
当使用Json.Net时,我理解如何将$ type属性放入渲染的json中,但有没有办法更改该字段名称?我需要使用"__type"而不是"$ type".
我有这样的课程
class Holder {
public int ObjType { get; set; }
public List<Base> Objects { get; set; }
}
abstract class Base {
// ... doesn't matter
}
class DerivedType1 : Base {
// ... doesn't matter
}
class DerivedType2 : Base {
// ... doesn't matter
}
Run Code Online (Sandbox Code Playgroud)
使用WebAPI我想要接收对象Holder并正确反序列化它.基于ObjType值,我需要Objects将要反序列化的属性作为List<DerivedType1>(ObjType == 1)或List<DerivedType2>(ObjType == 2).
目前我搜索了SO和互联网以获得最佳方法,但我找到的最好的是这个答案/sf/answers/562189841/.这个解决方案的问题是,它松散了父对象的上下文,所以我找不到它的值ObjType.OK,我可以创建自定义解决它JsonConverter用于Holder和remebering的ObjType价值,但我还是很affraid这行
serializer.Populate(jObject.CreateReader(), target); …Run Code Online (Sandbox Code Playgroud) 我有一个Newtonsoft JSON.NET JsonConverter来帮助反序列化其类型是抽象类的属性.它的要点看起来像这样:
public class PetConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Animal);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jsonObject = JObject.Load(reader);
if (jsonObject["Lives"] != null) return jsonObject.ToObject<Cat>(serializer);
if (jsonObject["StopPhrase"] != null) return jsonObject.ToObject<Parrot>(serializer);
return null;
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ throw new NotImplementedException(); }
}
Run Code Online (Sandbox Code Playgroud)
以下是它处理的类:
public …Run Code Online (Sandbox Code Playgroud) 我有以下问题,我无法解决:
我有不同的类,它们都实现了一个名为的接口IProtocol.的命名,现在,SimpleProtocol,ParallelProtocol.我想坚持这些对象,所以我使用JSON.NET,一切正常.除非我试图反序列化它们,当我知道它们应该是什么类型时,它会完美地工作,例如:
SimpleProtocol p = JsonConvert.DeserializeObject<SimpleProtocol>(myJsonData);
Run Code Online (Sandbox Code Playgroud)
但是,我现在处于需要加载JSON数据并IProtocol返回的情况,但可以理解的是,JSON不允许这样做; 例如,这样的事情并没有工作:
IProtocol p1 = JsonConvert.DeserializeObject<IProtocol>(myJsonData); // does not work
IProtocol p2 = (IProtocol)JsonConvert.DeserializeObject(myJsonData); // also, does not work
Run Code Online (Sandbox Code Playgroud)
所以,查找API我发现了这个方法签名:
public static Object DeserializeObject(
string value,
Type type
)
Run Code Online (Sandbox Code Playgroud)
看起来就像我需要的东西,所以通过将字符串中的类型持久化并检索它来尝试:
// test
Type protocolType = Type.GetType("MyApp.Protocols.SimpleProtocol");
IProtocol p1 = JsonConvert.DeserializeObject(myJsonData, protocolType);
Run Code Online (Sandbox Code Playgroud)
我得到一个错误,这是不可能投下Newtonsoft.Json.Linq.JObject到IProtocol.这很奇怪,我不知道如何解决这个问题.
在泛型方法中传递Type对象是不可能的,所以我基本上被困在这里.有没有办法解决这个问题,最好不要使用反射?在我看来,这是一个完全正常的用例.
我能做什么,但对我来说似乎有点"脏",是创建一个简单的包装类,它包含一个IProtocol实例并序列化/反序列化?
我是JSON的新手,请帮忙!
我试图将a序列List<KeyValuePair<string, string>>化为JSON
目前:
[{"Key":"MyKey 1","Value":"MyValue 1"},{"Key":"MyKey 2","Value":"MyValue 2"}]
Run Code Online (Sandbox Code Playgroud)
预期:
[{"MyKey 1":"MyValue 1"},{"MyKey 2":"MyValue 2"}]
Run Code Online (Sandbox Code Playgroud)
这是我的KeyValuePairJsonConverter:JsonConverter
public class KeyValuePairJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
List<KeyValuePair<object, object>> list = value as List<KeyValuePair<object, object>>;
writer.WriteStartArray();
foreach (var item in list)
{
writer.WriteStartObject();
writer.WritePropertyName(item.Key.ToString());
writer.WriteValue(item.Value.ToString());
writer.WriteEndObject();
}
writer.WriteEndArray();
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<KeyValuePair<object, object>>);
}
public override object ReadJson(JsonReader reader, Type objectType, …Run Code Online (Sandbox Code Playgroud) 我希望有这样的API:
public class RelayController : ApiController
{
// POST api/values
public void Post([FromBody]IDataRelayPackage package)
{
MessageQueue queue = new MessageQueue(".\\private$\\DataRelay");
queue.Send(package);
queue.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到'包'的空值,所以我想知道可能出错的地方.我唯一的想法是默认的JSON序列化程序无法处理这个,但我不清楚如何解决它.
c# ×9
json.net ×7
json ×3
asp.net-mvc ×2
.net ×1
casting ×1
interface ×1
keyvaluepair ×1
post ×1
types ×1