C# 正确的Json.net System.Object往返?

C# 正确的Json.net System.Object往返?,c#,.net,json.net,C#,.net,Json.net,使用Newtonsoft.Json库,想象一下 public class Test { public Object Obj { get; set; } } 现在,尝试这样序列化它 var json = JsonConvert.SerializeObject(new Test(){ Obj = new Uri(@"http://www.google.com") }); …将给我以下JSON { "Obj": "http://www.google.com" } 这显然不足以将其反

使用Newtonsoft.Json库,想象一下

public class Test
{
   public Object Obj { get; set; }
}
现在,尝试这样序列化它

var json = JsonConvert.SerializeObject(new Test(){ Obj = new Uri(@"http://www.google.com") });
…将给我以下JSON

{
    "Obj": "http://www.google.com"
}
这显然不足以将其反序列化回Uri对象,事实上,尝试反序列化它会给我一个String对象

是否有任何现有方法可以正确序列化和反序列化此处的类型信息,以便将对象作为Uri而不是字符串读回?在这种情况下,我只是尝试与.NET应用程序进行互操作,反序列化确切的类型非常重要


提前感谢。

JSON只知道JavaScript数据类型:字符串、数字和布尔值。URL不在列表中


事实上,JSON的全部要点是允许松散类型的传输。如果需要强类型传输,请查看更强大的传输协议,如WCF二进制序列化。

如果要将字符串转换回Uri,可以使用自定义转换器属性

 [JsonConverter(typeof(UriConverter))]
 public object Obj {get;set;}
转换器

public class UriConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
        {
            //try to create uri out of the string
            Uri uri;
            if(Uri.TryCreate(reader.Value.ToString(), UriKind.Absolute, out uri))
            {
                return uri;
            }
            //just a string -> return string value
            return reader.Value;
        }

        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        throw new InvalidOperationException("Unable to process JSON");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (null == value)
        {
            writer.WriteNull();
            return;
        }

        if (value is Uri)
        {
            writer.WriteValue(((Uri)value).OriginalString);
            return;
        }

        throw new InvalidOperationException("Unable to process JSON");
    }
}
以及use属性

 [JsonConverter(typeof(UriConverter))]
 public object Obj {get;set;}
然后,您应该能够确定底层对象是否与Uri类似

  var data = JsonConvert.DeserializeObject<YourObject>(yourJSONString);
  if (data.Obj is Uri)
  {
       ... add logic here
  }
  else
  {
       ... not Uri different logic
  }
var data=JsonConvert.DeserializeObject(yourJSONString);
if(data.Obj是Uri)
{
…在这里添加逻辑
}
其他的
{
…没有不同的逻辑
}

您还可以查看本文以了解更多信息

虽然我大体上同意JSON允许松散类型传输的意图,但JSON.net在.net类型方面具有灵活性(通过特殊的$type属性和TypeNameHandling设置)。碰巧它将一个Uri转换为一个字符串。。。在任何情况下,谢谢,我会考虑WCF二进制序列化。谢谢。如果System.Object总是一个Uri,那么这确实可以解决这个问题,但不幸的是,它不是(否则我只会更改类声明中的类型)。+1真棒,我使用JSON.NET多年了,不知道它有这么复杂!您应该能够重写转换器来处理您的场景,识别字符串是否为Uri,并相应地将其作为Uri返回。我将为您的场景重写转换器。我还想知道,如果Uri嵌套在Obj中,这个解决方案是否足够(即Obj不是一个Uri对象,但例如,一个对象[]也包含一个Uri…)。我承认,我对Json.net将无法控制地强制我的所有Uri对象为字符串感到恼火……反序列化为对象类型通常是个坏主意。通常情况下,属性应该只需要一种类型。最新更新是否适合您的场景?