我从外部来源接收Json数据。我需要将Json消息转换为XML。
使用NewtonSoft库,这相对简单:
var placeHolder = $"{{\"Data\": {jsonContent} }} ";
var xmlNode = JsonConvert.DeserializeXmlNode(placeHolder, "Root").OuterXml;
var doc = new XmlDocument();
doc.LoadXml(xmlNode);
我收到的关于Json的一件奇怪的事情打破了整个过程。
Json看起来像这样:
[
{
"Type": "Application",
"Object": {
"Duration": 2,
"Request": {
"authReference": "..",
"IdEnrolment": {
"username": "test",
"password": "***",
"createNewUser": false
}
},
"Type": "XXX.SomeController",
"Logs": [
],
"Method": "IdEnrolments",
"Response": {
"IdUsername": null,
"result": {
"resultCode": 0,
"resultTitle": null,
"resultMessage": null
}
}
}
},
{
"Type": "Proxy",
"Object": {
"Assembly": null,
"Policy": null,
"Cache": null,
"Duration": 516,
"Request": "{\"AuthenticateUserRequest\":{\"EnterpriseContext\":{\"ContextInfo\":{\"@xmlns\":\"http://example.xom\",\"ProcessContextId\":\"adad\",\"ExecutionContextId\":\"adac\"}\"}}",
"Type": "https://someserver/services/ent/informationandtechnologymanagement/company/v1",
"Logs": [
],
"Method": "AuthenticateUser",
"Response": "{\"AuthenticateUserResponse\":{\"EnterpriseContext\":{\"ContextInfo\":{\"@xmlns\":\"http://example.com\",\"ProcessContextId\":\"adad\",\"ExecutionContextId\":\"adad\"}}}}"
}
}
]
数组中的第一个对象是完美的,并且可以正确序列化。数组中的第二个对象引起混乱(可以理解)。该对象的Request和Response字段实际上是字符串,并且包含JSON代码。
有没有办法对此进行反序列化?我意识到有很多要求图书馆足够灵活地执行此操作的方法-但是我对如何使用它感到有些困惑。
我收到的所有消息看起来大致相同-但具体来说,Request和Response对象的内容取决于特定的请求/响应。
构建此代码的人没有任何形式的架构或协定,只是他们发送Json文本,并且他们似乎不愿意或无法更改Json的创建方式。
任何建议都将不胜感激。
注意:该行为似乎不是随机的。是否获得正确的对象或字符串由以下属性决定:“类型”:“应用程序” 。有许多不同的“类型”-有些已正确序列化,而另一些则没有。...Aaarrggghhh !!!!沮丧!!!!
答案 0 :(得分:0)
您的JSON在root / Type:Proxy / Object /中砖砌,请求嵌套格式错误:
"Request": "{\"AuthenticateUserRequest\":{\"EnterpriseContext\":{\"ContextInfo\":{\"@xmlns\":\"http://example.xom\",\"ProcessContextId\":\"adad\",\"ExecutionContextId\":\"adac\"}\"}}",
这里有4个花括号打开,但是只有3个花括号关闭。
答案 1 :(得分:0)
您必须处理的JSON非常不规则且很糟糕,因此您只需将所有这些信息解构为C#接口,类和结构,如下所示:
#region Fields
enum JsonObjType
{
Application,
Proxy,
SomeController,
}
#endregion
#region Classes
// Application
public class AppObj : JsonObjMaster
{
public readonly JsonObjType Type_Ind {get;}
public int Duration {get; set;}
public AppRequest Request {get; set;}
public AppObjController Controller {get; set;}
//you need a default constuctor for classes, cause else no json parser will work with them
public AppObj()
{
Type_Ind = JsonObjType.Application;
Duration = 0;
AppResult = String.Empty;
Request = new AppRequest();
Controller = new AppObjController();
}
}
public class AppObjController : JsonObjSlave
{
public readonly JsonObjType Type_Ind {get;}
public string[] Logs {get; set;}
public Func</*whatever is supposed to be here*/> Method {get; set;}
public AppResult Result {get; set;}
public AppObjController()
{
Type_Ind = JsonObjType.SomeController;
Log = Array.Empty<string>();
Method = (/*whatever is supposed to be here*/) => null; //may need to change depending on what the function is for
Result = new AppResult();
}
}
// Proxy
public class ProxyObj : JsonObjMaster
{
public readonly JsonObjType Type_Ind {get;}
public int Duration {get; set;}
public string Assembly {get; set;} //I am assuming strings here since no type is supplied
public string Policy {get; set;}
public string Cache {get; set;}
public string Request {get; set;}
public string Type {get; set;}
public string[] Logs {get; set;}
public Func</*whatever is supposed to be here*/> Method {get; set}
public string Response {get; set;}
public ProxyObj()
{
Type_Ind = JsonObjType.Proxy;
Duration = 0; //not needed but to stay consistent
Assembly = String.Empty();
Policy = String.Empty();
Cache = String.Empty();
Request = String.Empty();
Type = String.Empty();
Logs = Array.Empty<string>();
Method = (/*whatever is supposed to be here*/) => null; //may need to change depending on what the function is for
Response = String.Empty();
}
}
#endregion
#region Structs
// Interfaces
public interface JsonObjMaster
{
public readonly JsonObjType Type_Ind {get;}
public int Duration {get; set;}
}
public interface JsonObjSlave
{
public readonly JsonObjType Type_Ind {get;}
}
// Structs
public struct IdEnrolment
{
public string Username {get; set;}
public string Password {get; set;}
public bool CreateNewUser {get; set;}
}
public struct AppResult
{
public int Code {get; set;}
public string Title {get; set;}
public string Message {get; set;}
}
public struct AppRequest
{
public string AuthRefernece {get; set;}
public IdEnrolment {get; set;}
}
#endregion
为了将JSON加载到类中,您现在需要在JSON文件的上下文中向解析器提供C#对象属性的名称,以便解析器可以链接它们。看起来可能像这样:
[MyJsonparser.JsonName("Type")]
public string Type {get; set;}
但是它高度依赖于您使用的JSON库,因此您需要在他们的文档中进行查找。
如果您可以成功地将某人(希望不是您)所做的JSON麻烦转换为C#对象,则可以通过移至另一层类和结构来解析剩下的JSON字符串,然后可以将其用于处理。
现在,当您将JSON用作C#之后,您可以轻松地将其序列化为XML,但是可悲的是,由于JSON的实现程度很差,因此如果不使用C#对象作为元介质,就无法自动执行该操作。