Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net JSON或XML对象序列化和创建,包括字段类型_C#_.net_Xml_Json_Serialization - Fatal编程技术网

C# .net JSON或XML对象序列化和创建,包括字段类型

C# .net JSON或XML对象序列化和创建,包括字段类型,c#,.net,xml,json,serialization,C#,.net,Xml,Json,Serialization,我试图将动态DTO映射到JSON或XML,但要获得关于字段类型的信息。 所以我想知道,从这个物体上看,是否有可能: public class AddressDto { public string Street { get; set; } } public class UserInfoDto { public string UserName { get; set; } public int Age {

我试图将动态DTO映射到JSON或XML,但要获得关于字段类型的信息。 所以我想知道,从这个物体上看,是否有可能:

public class AddressDto
    {
        public string Street { get; set; }
    }
public class UserInfoDto
    {
        public string UserName { get; set; }            
        public int Age { get; set; }
        public AddressDto Address { get; set; }
    }
要在JSON(或XML)中获得类似的内容:


…反之亦然。

是的,这是可能的,但您必须做一些工作来指导序列化程序如何格式化输出字符串。如果您想坚持使用内置的.NET序列化程序,可以使用
System.Runtime.Serialization.Json.DataContractJsonSerializer
类来实现这一点

1-创建MetadataObject类作为输出数据的包装器对象

定义以下类并用
[DataContract]
标记它,以便可以序列化它:

[DataContract]
public class MetadataObject
{
    [DataMember(Name = "fieldType")]
    public string FieldType { get; set; }

    [DataMember(Name = "fieldName")]
    public string FieldName { get; set; }

    [DataMember(Name = "fieldValue")]
    public object FieldValue { get; set; }
}
2-告诉序列化程序如何序列化父对象(UserInfoDto)

为此,您需要让
UserInfoDto
对象实现
ISerializable
接口(更具体地说,是
GetObjectData()
方法),并将其标记为
[Serializable]
。您还需要包含此类将包含的所有自定义类型。在这种情况下,它将是
AddressDto
类型,以及
List
,在
GetObjectData()
方法中构造。最后一个类如下所示:

[KnownType(typeof(AddressDto))]
[KnownType(typeof(List<MetadataObject>))]
[Serializable]
public class UserInfoDto : ISerializable
{
    public string UserName { get; set; }

    public int Age { get; set; }

    public AddressDto Address { get; set; }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        var nodes = this.GetType().GetProperties().Select(property =>
        {
            return new MetadataObject
            {
                FieldType = property.PropertyType.Name,
                FieldName = property.Name,
                FieldValue = property.GetValue(this, null)
            };
        }).ToList();

        info.AddValue("fieldType", this.GetType().Name);
        info.AddValue("objectValue", nodes);
    }
}
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UserInfoDto));

var data = new UserInfoDto { Age = 30, UserName = "John" };
data.Address = new AddressDto { Street = "123 ABC" };

using (MemoryStream stream = new MemoryStream())
{
    using (StreamReader reader = new StreamReader(stream))
    {
        serializer.WriteObject(stream, data);
        stream.Position = 0;

        var output = reader.ReadToEnd();
    }
}
{  
   "fieldType":"UserInfoDto",
   "objectValue":[  
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"UserName",
         "fieldType":"String",
         "fieldValue":"John"
      },
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"Age",
         "fieldType":"Int32",
         "fieldValue":30
      },
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"Address",
         "fieldType":"AddressDto",
         "fieldValue":{  
            "__type":"AddressDto:#StackOverflow.Console",
            "fieldType":"String",
            "fieldName":"Street",
            "fieldValue":"123 ABC"
         }
      }
   ]
}
4-将其全部放在一起

最后,按如下方式定义序列化程序:

[KnownType(typeof(AddressDto))]
[KnownType(typeof(List<MetadataObject>))]
[Serializable]
public class UserInfoDto : ISerializable
{
    public string UserName { get; set; }

    public int Age { get; set; }

    public AddressDto Address { get; set; }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        var nodes = this.GetType().GetProperties().Select(property =>
        {
            return new MetadataObject
            {
                FieldType = property.PropertyType.Name,
                FieldName = property.Name,
                FieldValue = property.GetValue(this, null)
            };
        }).ToList();

        info.AddValue("fieldType", this.GetType().Name);
        info.AddValue("objectValue", nodes);
    }
}
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UserInfoDto));

var data = new UserInfoDto { Age = 30, UserName = "John" };
data.Address = new AddressDto { Street = "123 ABC" };

using (MemoryStream stream = new MemoryStream())
{
    using (StreamReader reader = new StreamReader(stream))
    {
        serializer.WriteObject(stream, data);
        stream.Position = 0;

        var output = reader.ReadToEnd();
    }
}
{  
   "fieldType":"UserInfoDto",
   "objectValue":[  
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"UserName",
         "fieldType":"String",
         "fieldValue":"John"
      },
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"Age",
         "fieldType":"Int32",
         "fieldValue":30
      },
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"Address",
         "fieldType":"AddressDto",
         "fieldValue":{  
            "__type":"AddressDto:#StackOverflow.Console",
            "fieldType":"String",
            "fieldName":"Street",
            "fieldValue":"123 ABC"
         }
      }
   ]
}
运行此操作时,
输出
如下所示:

[KnownType(typeof(AddressDto))]
[KnownType(typeof(List<MetadataObject>))]
[Serializable]
public class UserInfoDto : ISerializable
{
    public string UserName { get; set; }

    public int Age { get; set; }

    public AddressDto Address { get; set; }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        var nodes = this.GetType().GetProperties().Select(property =>
        {
            return new MetadataObject
            {
                FieldType = property.PropertyType.Name,
                FieldName = property.Name,
                FieldValue = property.GetValue(this, null)
            };
        }).ToList();

        info.AddValue("fieldType", this.GetType().Name);
        info.AddValue("objectValue", nodes);
    }
}
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UserInfoDto));

var data = new UserInfoDto { Age = 30, UserName = "John" };
data.Address = new AddressDto { Street = "123 ABC" };

using (MemoryStream stream = new MemoryStream())
{
    using (StreamReader reader = new StreamReader(stream))
    {
        serializer.WriteObject(stream, data);
        stream.Position = 0;

        var output = reader.ReadToEnd();
    }
}
{  
   "fieldType":"UserInfoDto",
   "objectValue":[  
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"UserName",
         "fieldType":"String",
         "fieldValue":"John"
      },
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"Age",
         "fieldType":"Int32",
         "fieldValue":30
      },
      {  
         "__type":"MetadataObject:#StackOverflow.Console",
         "fieldName":"Address",
         "fieldType":"AddressDto",
         "fieldValue":{  
            "__type":"AddressDto:#StackOverflow.Console",
            "fieldType":"String",
            "fieldName":"Street",
            "fieldValue":"123 ABC"
         }
      }
   ]
}

请注意,
\u type
属性由序列化程序自动生成。如果您使用的是.NET 4.5,您可以(如果字符串需要反序列化回对象中,您可能需要它们)

是否希望自动执行此操作?因为我脑子里有一个手动的解决方案(实际上很乏味)。自动的会更好。我可以通过手动使用反射生成一些自定义JSON或XML来实现这一点,但当我需要将其转换回源对象时,我遇到了一些问题。因此,如果您有任何解决方案,请随意分享。这是一个很好的解决方案,但我需要它来处理任何自定义数据,我不能这样修改(我不能添加[Serializable]anotation或任何其他更改)。它应该能够处理通过第三方程序集的反射加载的对象。在这种情况下,您需要定义自己的数据协定序列化程序,坦率地说,.NET Json库会让您感到痛苦。看看Json.NET。