Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.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# 如何编写一个接受Json的Web服务;多类型属性“;?_C#_Json_Web Services_Wcf_Asp.net Web Api - Fatal编程技术网

C# 如何编写一个接受Json的Web服务;多类型属性“;?

C# 如何编写一个接受Json的Web服务;多类型属性“;?,c#,json,web-services,wcf,asp.net-web-api,C#,Json,Web Services,Wcf,Asp.net Web Api,上下文: Cust有一个发送以下json的服务。他可以轻松地更改该查询的目标,但不能更改查询本身 我必须构建一个接受查询的Web服务,如下面的JSON。 虽然处理Json不会有问题,但我在尝试定义接受类似查询的方法/接口时遇到了问题 这个问题来自Houses>Things:它是一个字符串字典,“objectThing”,其中“objectThing”有一个属性值,可以包含多种类型。 例如: int,“值”:42 字符串,“值”:“Catty” 字符串数组,“值”:[“Book1”、“Book2

上下文:
Cust有一个发送以下json的服务。他可以轻松地更改该查询的目标,但不能更改查询本身

我必须构建一个接受查询的Web服务,如下面的JSON。 虽然处理Json不会有问题,但我在尝试定义接受类似查询的方法/接口时遇到了问题

这个问题来自Houses>Things:它是一个字符串字典,“
objectThing
”,其中“
objectThing
”有一个属性值,可以包含多种类型。
例如:

  • int,
    “值”:42
  • 字符串,
    “值”:“Catty”
  • 字符串数组,
    “值”:[“Book1”、“Book2”、“Book3”]
  • 对象,对象类型的有限列表
    "Value": 
          {
            "PeopleId": "1234ABCD",
            "Name": "John"
          }
    
    "Value": [
          {
            "PeopleId": "1234ABCD",
            "Name": "John"
          },
          {
            "PeopleId": "0000AAAA",
            "Name": "Doe"
          }
     ]
    
  • 对象数组,具有有限对象类型列表的数组
    "Value": 
          {
            "PeopleId": "1234ABCD",
            "Name": "John"
          }
    
    "Value": [
          {
            "PeopleId": "1234ABCD",
            "Name": "John"
          },
          {
            "PeopleId": "0000AAAA",
            "Name": "Doe"
          }
     ]
    
    价值对我来说不是动态的。它在我可以定义的有限类型列表中
Json示例:

{
    "RootID"    : "0123456",
    "FooID"     : "0123456",    
    "BarID"     : "0123456",
    "Houses"    :[
        {
            "OwnerId"   : "0123456",
            "Date"      : 1890895600000,
            "Location"  : {
                "Latitude"  : -1,
                "Longitude" : -1
            },

            "Things" :{
                "1" :{
                    "Label": "Books",                   
                    "Type" : "List",
                    "Value": ["Book1", "Book2", "Book3"]
                },
                "2" :{
                    "Label": "Cat",                 
                    "Type" : "Text",
                    "Value": "Catty"
                },
                "3" :{
                    "Label": "A Number",                    
                    "Type" : "Int",
                    "Value": 42
                },
                "4" :{
                    "Label": "Peoples",                 
                    "Type" : "People",
                    "Value": [
                        {
                          "PeopleId": "1234ABCD",
                          "Name": "John"
                        },
                        {
                          "PeopleId": "0000AAAA",
                          "Name": "Doe"
                        }
                    ]
                }               
            }
        },
        {       
            "OwnerId"   : "111111",
            "Things" :{}
        },
        {       
            "OwnerId"   : "000001",
            "Things" :{}
        }   
    ]
}
以及类定义,如果我要将这个Json反序列化为适当的类型:

using System;
using System.Collections.Generic;

using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public partial class QueryRoot
{
    [JsonProperty("RootID")]
    public string RootId { get; set; }

    [JsonProperty("FooID")]
    public string FooId { get; set; }

    [JsonProperty("BarID")]
    public string BarId { get; set; }

    [JsonProperty("Houses")]
    public List<House> Houses { get; set; }
}

public partial class House
{
    [JsonProperty("OwnerId")]
    public string OwnerId { get; set; }

    [JsonProperty("Date", NullValueHandling = NullValueHandling.Ignore)]
    public long? Date { get; set; }

    [JsonProperty("Location", NullValueHandling = NullValueHandling.Ignore)]
    public Location Location { get; set; }

    [JsonProperty("Things")]
    public Dictionary<string, Thing> Things { get; set; }
}

public partial class Location
{
    [JsonProperty("Latitude")]
    public long Latitude { get; set; }

    [JsonProperty("Longitude")]
    public long Longitude { get; set; }
}

public partial class Thing
{
    [JsonProperty("Label")]
    public string Label { get; set; }

    [JsonProperty("Type")]
    public string Type { get; set; }

    [JsonProperty("Value")]
    public ThingValue Value { get; set; }
}

public partial class ValueClass
{
    [JsonProperty("PeopleId")]
    public string PeopleId { get; set; }

    [JsonProperty("Name")]
    public string Name { get; set; }
}

public partial struct ValueElement
{
    public string String;
    public ValueClass ValueClass;

    public static implicit operator ValueElement(string String) => new ValueElement { String = String };
    public static implicit operator ValueElement(ValueClass ValueClass) => new ValueElement { ValueClass = ValueClass };
}

public partial struct ThingValue
{
    public List<ValueElement> AnythingArray;
    public long? Integer;
    public string String;

    public static implicit operator ThingValue(List<ValueElement> AnythingArray) => new ThingValue { AnythingArray = AnythingArray };
    public static implicit operator ThingValue(long Integer) => new ThingValue { Integer = Integer };
    public static implicit operator ThingValue(string String) => new ThingValue { String = String };
}

public partial class QueryRoot
{
    public static QueryRoot FromJson(string json) => JsonConvert.DeserializeObject<QueryRoot>(json, QuickType.Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this QueryRoot self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters =
        {
            ThingValueConverter.Singleton,
            ValueElementConverter.Singleton,
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}

internal class ThingValueConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(ThingValue) || t == typeof(ThingValue?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.Integer:
                var integerValue = serializer.Deserialize<long>(reader);
                return new ThingValue { Integer = integerValue };
            case JsonToken.String:
            case JsonToken.Date:
                var stringValue = serializer.Deserialize<string>(reader);
                return new ThingValue { String = stringValue };
            case JsonToken.StartArray:
                var arrayValue = serializer.Deserialize<List<ValueElement>>(reader);
                return new ThingValue { AnythingArray = arrayValue };
        }
        throw new Exception("Cannot unmarshal type ThingValue");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        var value = (ThingValue)untypedValue;
        if (value.Integer != null)
        {
            serializer.Serialize(writer, value.Integer.Value);
            return;
        }
        if (value.String != null)
        {
            serializer.Serialize(writer, value.String);
            return;
        }
        if (value.AnythingArray != null)
        {
            serializer.Serialize(writer, value.AnythingArray);
            return;
        }
        throw new Exception("Cannot marshal type ThingValue");
    }

    public static readonly ThingValueConverter Singleton = new ThingValueConverter();
}

internal class ValueElementConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(ValueElement) || t == typeof(ValueElement?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.String:
            case JsonToken.Date:
                var stringValue = serializer.Deserialize<string>(reader);
                return new ValueElement { String = stringValue };
            case JsonToken.StartObject:
                var objectValue = serializer.Deserialize<ValueClass>(reader);
                return new ValueElement { ValueClass = objectValue };
        }
        throw new Exception("Cannot unmarshal type ValueElement");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        var value = (ValueElement)untypedValue;
        if (value.String != null)
        {
            serializer.Serialize(writer, value.String);
            return;
        }
        if (value.ValueClass != null)
        {
            serializer.Serialize(writer, value.ValueClass);
            return;
        }
        throw new Exception("Cannot marshal type ValueElement");
    }

    public static readonly ValueElementConverter Singleton = new ValueElementConverter();
}
使用系统;
使用System.Collections.Generic;
利用制度全球化;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Converters;
公共部分类QueryRoot
{
[JsonProperty(“RootID”)]
公共字符串RootId{get;set;}
[JsonProperty(“FooID”)]
公共字符串FooId{get;set;}
[JsonProperty(“BarID”)]
公共字符串BarId{get;set;}
[JsonProperty(“房屋”)]
公共列表屋{get;set;}
}
公屋
{
[JsonProperty(“所有者ID”)]
公共字符串所有者ID{get;set;}
[JsonProperty(“日期”,NullValueHandling=NullValueHandling.Ignore)]
公共长日期{get;set;}
[JsonProperty(“位置”,NullValueHandling=NullValueHandling.Ignore)]
公共位置位置{get;set;}
[JsonProperty(“事物”)]
公共字典事物{get;set;}
}
公共部分类位置
{
[JsonProperty(“纬度”)]
公共长纬度{get;set;}
[JsonProperty(“经度”)]
公共长经度{get;set;}
}
公共部分阶级事物
{
[JsonProperty(“标签”)]
公共字符串标签{get;set;}
[JsonProperty(“类型”)]
公共字符串类型{get;set;}
[JsonProperty(“价值”)]
公共ThingValue{get;set;}
}
公共部分类ValueClass
{
[JsonProperty(“PeopleId”)]
公共字符串PeopleId{get;set;}
[JsonProperty(“名称”)]
公共字符串名称{get;set;}
}
公共部分结构ValueElement
{
公共字符串;
公共价值阶层;
公共静态隐式运算符ValueElement(string)=>new ValueElement{string=string};
公共静态隐式运算符ValueElement(ValueClass ValueClass)=>new ValueElement{ValueClass=ValueClass};
}
公共部分结构ThingValue
{
公开列出任何事情;
公共长整数;
公共字符串;
公共静态隐式运算符ThingValue(List AnythingArray)=>newthingvalue{AnythingArray=AnythingArray};
公共静态隐式运算符ThingValue(长整数)=>newthingvalue{Integer=Integer};
公共静态隐式运算符ThingValue(string string)=>newthingvalue{string=string};
}
公共部分类QueryRoot
{
公共静态QueryRoot FromJson(字符串json)=>JsonConvert.DeserializeObject(json,QuickType.Converter.Settings);
}
公共静态类序列化
{
公共静态字符串ToJson(此QueryRoot self)=>JsonConvert.SerializeObject(self,QuickType.Converter.Settings);
}
内部静态类转换器
{
公共静态只读JsonSerializerSettings设置=新JsonSerializerSettings
{
MetadataPropertyHandling=MetadataPropertyHandling.Ignore,
DateParseHandling=DateParseHandling.None,
转换器=
{
ThingValueConverter.Singleton,
ValueElementConverter.Singleton,
新的IsoDateTimeConverter{DateTimeStyles=DateTimeStyles.AssumeUniversal}
},
};
}
内部类ThingValueConverter:JsonConverter
{
公共覆盖布尔CanConvert(Type t)=>t==typeof(ThingValue)| | t==typeof(ThingValue?);
公共重写对象ReadJson(JsonReader阅读器,类型t,对象existingValue,JsonSerializer序列化程序)
{
开关(reader.TokenType)
{
案例JsonToken.Integer:
var integerValue=序列化程序。反序列化(读取器);
返回新的ThingValue{Integer=integerValue};
case JsonToken.String:
案例JsonToken。日期:
var stringValue=serializer.Deserialize(读取器);
返回新的ThingValue{String=stringValue};
案例JsonToken.StartArray:
var arrayValue=序列化程序。反序列化(读取器);
返回新的ThingValue{AnythingArray=arrayValue};
}
抛出新异常(“无法解组类型ThingValue”);
}
public override void WriteJson(JsonWriter编写器、对象非类型化值、JsonSerializer序列化器)
{
var值=(ThingValue)非类型值;
如果(value.Integer!=null)
{
serializer.Serialize(writer,value.Integer.value);
回来
}
if(value.String!=null)
{
serializer.Serialize(writer,value.String);
回来
}
if(value.AnythingArray!=null)
{
serializer.Serialize(writer、value.AnythingArray);
回来
}
抛出新异常(“无法封送类型ThingValue”);
}
public static readonly ThingValueConverter Singleton=new ThingValueConverter();
}
内部类ValueElementConverter:JsonConverter
{
公共覆盖布尔CanConvert(Type t)=>t==typeof(ValueElement)| | t==typeof(ValueElement?);
公共重写对象ReadJson(JsonReader reader,类型t,对象existingValue,
    public class JsonHelper
{
    public static string JsonSerializer<T>(T t)
    {
        var ser = new DataContractJsonSerializer(typeof(T));
        var ms = new MemoryStream();
        ser.WriteObject(ms, t);
        string jsonString = Encoding.UTF8.GetString(ms.ToArray());
        ms.Close();
        return jsonString;
    }
    public static T JsonDeserialize<T>(string jsonString)
    {
        var ser = new DataContractJsonSerializer(typeof(T));
        var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        var obj = (T)ser.ReadObject(ms);
        return obj;
    }
}