Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.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.NET自定义反序列化_C#_.net_Json_Serialization_Json.net - Fatal编程技术网

C# 使用Json.NET自定义反序列化

C# 使用Json.NET自定义反序列化,c#,.net,json,serialization,json.net,C#,.net,Json,Serialization,Json.net,我有一节课 public class Order { public int Id { get; set; } public string ShippingMethod { get; set; } } 我想将下面的JSON数据反序列化到上面的类/对象中 string json = @"{ 'Id': 1, 'ShippingMethod': { 'Code': 'external_DHLExpressWorldwide', 'Description': '

我有一节课

public class Order
{
   public int Id { get; set; }
   public string ShippingMethod { get; set; }
}
我想将下面的JSON数据反序列化到上面的类/对象中

string json = @"{
  'Id': 1,
  'ShippingMethod': {
     'Code': 'external_DHLExpressWorldwide',
     'Description': 'DHL ILS Express Worldwide'
  }
}";
我的想法是JSON中的
ShippingMethod
是一个对象,但我只想进入
ShippingMethod.code
(JSON中),它将在反序列化过程中以
Order
类中的
string
形式传递到
ShippingMethod

我怎样才能用计算机实现这个目标


我相信我可以用它来适应。但我感到困惑。文档中的示例仅适用于
WriteJson
,而不适用于
ReadJson

,您可以使用
JsonProperty
JsonIgnore
属性来指导反序列化过程。。。因此,您的模型可以是:

public class Order
{
    public int Id { get; set; }

    [JsonIgnore]
    public string ShippingMethod
    {
        get
        {
            return (string)TempShippingMethod?["Code"];
        }
    }

    [JsonProperty("ShippingMethod")]
    private JObject TempShippingMethod { set; get; }
}

var res=JsonConvert.DeserializeObject(json);
将对象反序列化为动态对象,然后通过访问动态对象属性来填充
顺序
对象

正如我在问题中提到的,我只是使用解决我的问题。下面是我的完整代码:

public class Order
{
    public int Id { get; set; }

    [JsonConverter(typeof(ShippingMethodConverter))]
    public string ShippingMethod { get; set; }
}

public class ShippingMethodConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException("Not implemented yet");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return string.Empty;
        } 
        else if (reader.TokenType == JsonToken.String)
        {
            return serializer.Deserialize(reader, objectType);
        }
        else
        {
            JObject obj = JObject.Load(reader);
            if (obj["Code"] != null) 
                return obj["Code"].ToString();
            else 
                return serializer.Deserialize(reader, objectType);
        }
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}

所以
code
Description
ShippingMethod
中?如何序列化?您只需要将“Id”和“Code”放在同一个级别?是的,这是我的问题,我想实现的ShippingMethod是json中的对象和C#类中的字符串。如何绘制这张地图。您必须按以下方式更改代码。@Aruna请看我如何将其映射为+1。我认为这是没有属性污染和新类创建的最好的清洁方式:)谢谢你的回答,但是如果还有很多其他属性,那么它就不合适了。你没有说还有更多的属性需要管理。为了解决这个问题,您可以添加一个映射一次的扩展方法,然后您可以在任何地方使用它。但你的解决方案似乎还可以,只是两个属性的代码行太多(在我看来)是的,看起来有很多代码,但实际上它会保持你的模型干净。是的,这只是一个小小的漏洞。我不喜欢这种方式,但我投票:)作为我对你的尊敬answer@Habibillah我也不喜欢你的答案,因为它太繁琐,不适合做简单的事情,但出于对你观点的尊重,我发布了我答案的简化版本……不用担心:)。问题很简单,但我的真实想法是,有很多属性和糟糕的json模式,它确实值得。例子。保存订单时,必须传递字符串,但要获取订单详细信息,需要一个对象。还有很多我不同意这是一个黑客行为。JsonIgnore就是为这种目的而设计的——这意味着您不必重新编写序列化。大概,我们缺少了一些上下文来解释为什么这不适合OP。
 dynamic o = JsonConvert.DeserializeObject(json);
 var order = new Order
 {
     Id = o.Id,
     ShippingMethod = o.ShippingMethod.Code
 };
public class Order
{
    public int Id { get; set; }

    [JsonConverter(typeof(ShippingMethodConverter))]
    public string ShippingMethod { get; set; }
}

public class ShippingMethodConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException("Not implemented yet");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return string.Empty;
        } 
        else if (reader.TokenType == JsonToken.String)
        {
            return serializer.Deserialize(reader, objectType);
        }
        else
        {
            JObject obj = JObject.Load(reader);
            if (obj["Code"] != null) 
                return obj["Code"].ToString();
            else 
                return serializer.Deserialize(reader, objectType);
        }
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}