如果 JSON 语法解析不好,请对其进行解析



如果 JSON 数据没有从 newtonsoft json 很好地解析,我该如何解析它。请参考我下面的代码:

var web_uri = new Uri("www.example.com"); 
var resp = await client2.GetAsync(web_uri); 
var resp_to_str = await resp.Content.ReadAsStringAsync(); 
var json_obj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(resp_to_str);

最后,我解析了 JSON。 现在,它按预期生成。

   {
        "Sex": "Male",
        "category": "A",
        "ID": 14,
        "created": "2016-03-03",
        "Tag": "2340",
        "members": [{
            "type": "A",
            "name": "fam_mem",
            "state": "ca",
            "Family": {
                "myGuardName": "tony",
                "details": [{
                    "address": "ca",
                    "type": "A"
                }]
            }
        }]
    }

  **RootObject omyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json_obj);** 

现在我在上面一行出现错误:System.Linq.Expressions 中发生了类型为"Microsoft.CSharp.RuntimeBinder.RuntimeBinderException"的异常.dll但未在用户代码中处理

其他信息:'Newtonsoft.Json.JsonConvert.DeserializeObject(string)' 的最佳重载方法匹配有一些无效参数

public class Detail
{
    public string address { get; set; }
    public string type { get; set; }
}
public class Family
{
    public string myGuardName { get; set; }
    public List<Detail> details { get; set; }
}
public class Member
{
    public string type { get; set; }
    public string name { get; set; }
    public string state { get; set; }
    public Family Family { get; set; }
}
public class RootObject
{
    public string Sex { get; set; }
    public string category { get; set; }
    public int ID { get; set; }
    public string created { get; set; }
    public string Tag { get; set; }
    public List<Member> members { get; set; }
}
TextBlock.Text = omyclass

我已经更新了问题

希望对您有所帮助:

var web_uri = new Uri("www.example.com");
var resp = await client2.GetAsync(web_uri);
var resp_to_str = await resp.Content.ReadAsStringAsync();
RootObject omyclass = JsonConvert.DeserializeObject<RootObject>(resp_to_str); //pass the response string here.

根据OP的评论更新:

textBlock2.Text = omyclass + "----!";不起作用,因为 omyclass 是RootObject,而不是string

您必须获取所需的信息并将其附加到textBlock2

textBlock2.text = omyclass.Sex + "----!";


更新 2(OP 获取字符串作为键值对):

用法:textBlock2.text = omyclass + "----!";

覆盖RootObject.ToString()并使用Reflection获取属性和属性值

public class RootObject
{
    public string Sex { get; set; }
    public string category { get; set; }
    public int ID { get; set; }
    public string created { get; set; }
    public string Tag { get; set; }
    public List<Member> members { get; set; }
    public override string ToString()
    {
        var values = new List<string>();
        foreach (var property in GetType().GetProperties())
        {
            values.Add(property.Name + ": " + property.GetValue(this));
        }
        return string.Join(", ", values);
    }
}

问题是JsonConvert.DeserializeObject<T>(string)期望一个字符串作为输入参数 - 但你没有传入字符串。 您正在传入json_obj这是上一次反序列化调用返回的dynamic

var json_obj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(resp_to_str);
var omyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json_obj);

JsonConvert从第一个dynamic调用返回的内容实际上是一个包含 LINQ 到 JSON 令牌树的JToken,而不是字符串。 这会导致在进行第二次调用时出现RuntimeBinderException

无需以这种方式对 JSON 字符串进行双重反序列化。 只需将resp_to_str传递给JsonConvert.DeserializeObject<RootObject>()

var omyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(resp_to_str);

原型小提琴。

更新

如果要在文本框中查看反序列化类的所有字段和属性,可以将其重新序列化为 JSON:

var reserializedJson = JsonConvert.SerializeObject(omyclass, Formatting.Indented);
textBlock2.Text = reserializedJson;

如果你这样做

textBlock2.Text = omyclass + "----!"

您只是显示类的ToString()值。 由于您没有覆盖此方法,因此它只会显示类名。

如果不想重新序列化,可以使用以下扩展方法:

public static class ObjectExtensions
{
    public static StringBuilder ToStringWithReflection<T>(this T obj, StringBuilder sb)
    {
        sb = sb ?? new StringBuilder();
        if (obj == null)
            return sb;
        if (obj is IEnumerable)
        {
            sb.Append("[");
            var first = true;
            foreach (var item in ((IEnumerable)obj))
            {
                if (!first)
                    sb.Append(",");
                sb.Append(item == null ? "" : item.ToString());
                first = false;
            }
            sb.Append("]");
        }
        else
        {
            var type = obj.GetType();
            var fields = type.GetFields();
            var properties = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0 && p.GetGetMethod(true) != null && p.CanRead);
            var query = fields
                .Select(f => new KeyValuePair<string, object>(f.Name, f.GetValue(obj)))
                .Concat(properties
                    .Select(p => new KeyValuePair<string, object>(p.Name, p.GetValue(obj, null))));
            sb.Append("{").Append(obj.GetType().Name).Append(": ");
            var first = true;
            foreach (var pair in query)
            {
                if (!first)
                    sb.Append(", ");
                sb.Append(pair.Key).Append(": ");
                if (pair.Value is IEnumerable && !(pair.Value is string))
                    pair.Value.ToStringWithReflection(sb);
                else
                    sb.Append(pair.Value == null ? "null" : pair.Value.ToString());
                first = false;
            }
            sb.Append("}");
        }
        return sb;
    }
    public static string ToStringWithReflection<T>(this T obj)
    {
        return obj.ToStringWithReflection(new StringBuilder()).ToString();
    }
}

然后做

textBlock2.Text = omyclass.ToStringWithReflection() + "----!"

更新 2

或者,如果要递归包含对象层次结构中的属性,则可以重写每个属性的 ToString() 方法,如下所示:

public class Detail
{
    public string address { get; set; }
    public string type { get; set; }
    public override string ToString() { return this.ToStringWithReflection(); }
}
public class Family
{
    public string myGuardName { get; set; }
    public List<Detail> details { get; set; }
    public override string ToString() { return this.ToStringWithReflection(); }
}
public class Member
{
    public string type { get; set; }
    public string name { get; set; }
    public string state { get; set; }
    public Family Family { get; set; }
    public override string ToString() { return this.ToStringWithReflection(); }
}
public class RootObject
{
    public string Sex { get; set; }
    public string category { get; set; }
    public int ID { get; set; }
    public string created { get; set; }
    public string Tag { get; set; }
    public List<Member> members { get; set; }
    public override string ToString() { return this.ToStringWithReflection(); }
}

然后ToString()输出将是:

{RootObject: Sex: Male, category: A, ID: 14, created: 2016-03-03, Tag: 2340, members: [{Member: type: A, name: fam_mem, state: ca, Family: {Family: myGuardName: tony, details: [{Detail: address: ca, type: A}]}}]}
您可以使用

自定义 JSON 格式化程序并按照您想要的方式解析它。它可以在框架级别实现,以便根据您的要求解析所有数据。从 MediaType格式化程序继承自定义格式化程序。

实现 MediaTypeFormatter.Pasre 的虚拟和抽象函数,根据您的要求在此处访问数据。

我已经以这种方式实现了格式化程序,它甚至解析了复杂的数据以匹配我想要的数据。

序列化复杂 Json 时,如果未正确反序列化,则值变为 null。要反序列化复杂的 Json,请使用 JsonMediaTypeFormatter。
我的例子
在您的配置文件中添加

config.Formatters.Clear();
    config.Formatters.Insert(0, new JsonNetFormatterDecide());  // My custom formatter
       config.Formatters.Insert(1, new JsonMediaTypeFormatter());//Default Formatter
    config.MapHttpAttributeRoutes();`

所以我使用我的自定义格式化程序进行所有获取操作。根据需要格式化数据并发送到客户端。我面临的问题是在接受复杂的Json数据(例如Jsonobjects中的Jsonarrays)时。所以在我的配置文件中,我在 Config.formatters 的索引 1 中添加了 JsonMediaTypeFormatter()。

在我的自定义格式化程序中

public override bool CanReadType(Type type)
{
    return false;
}

这使得JsonMediaType格式化程序是一个非常流行的格式化程序,用于反序列化复杂数据以进行反序列化。

底线是您可以使用JsonMediaTypeFormatter来反序列化复杂的 Json 数据

它有一些预定义的函数来反序列化。

通过查看您的 Json,似乎 Json 对象中的 Json 数组是您的 Json 无法正确反序列化的原因

如果你打算编写你的自定义 Json 格式化程序,你可以在框架级别实现,比如

public class JsonNetFormatterDecide : MediaTypeFormatter
{   
    //......
    public override bool CanReadType(Type type)
    {
        return false; //this causes the // project to use the second formatter in the config file ie,JsonMediaTypeFormatter  or the //default Json Formatter
    }
} 

相关内容

  • 没有找到相关文章

最新更新