有没有一种方法可以序列化Json,它包含一个字段,该字段包含更多json作为XML的字符串

时间:2019-09-18 09:26:28

标签: c# json xml json.net

我从外部来源接收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 !!!!沮丧!!!!

2 个答案:

答案 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#对象作为元介质,就无法自动执行该操作。