如何在没有名称的情况下将JSON序列化为C#类

时间:2016-11-29 16:00:06

标签: c# json serialization

我从Toggl API收到以下JSON数据:

[
  {
    "id": 1234567,
    "name": "My Workspace",
    "profile": 100,
    "premium": true,
    "admin": true,
    "default_hourly_rate": 1000,
    "default_currency": "USD",
    "only_admins_may_create_projects": true,
    "only_admins_see_billable_rates": true,
    "only_admins_see_team_dashboard": true,
    "projects_billable_by_default": true,
    "rounding": 0,
    "rounding_minutes": 0,
    "api_token": "some-api-token",
    "at": "2010-10-11T20:09:29+00:00",
    "logo_url": "https://assets.toggl.com/logos/i-am-awesome.png",
    "ical_url": "/ical/workspace_user/mr-awesome",
    "ical_enabled": true,
    "subscription": {
      "workspace_id": 0,
      "deleted_at": null,
      "created_at": "0001-01-01T00:00:00Z",
      "updated_at": null,
      "vat_valid": false,
      "vat_validated_at": null,
      "vat_invalid_accepted_at": null,
      "vat_invalid_accepted_by": null,
      "description": "Pro monthly",
      "vat_applicable": false
    }
  }
]

我在Visual Studio 2015 Paste Special... Paste JSON as Classes菜单上使用了方便的Edit来获得以下类结构:

public class TogglWorkspaceTest
{

    public class Rootobject
    {
        public Class1[] Property1 { get; set; }
    }

    public class Class1
    {
        public int id { get; set; }
        public string name { get; set; }
        public int profile { get; set; }
        public bool premium { get; set; }
        public bool admin { get; set; }
        public int default_hourly_rate { get; set; }
        public string default_currency { get; set; }
        public bool only_admins_may_create_projects { get; set; }
        public bool only_admins_see_billable_rates { get; set; }
        public bool only_admins_see_team_dashboard { get; set; }
        public bool projects_billable_by_default { get; set; }
        public int rounding { get; set; }
        public int rounding_minutes { get; set; }
        public string api_token { get; set; }
        public DateTime at { get; set; }
        public string logo_url { get; set; }
        public string ical_url { get; set; }
        public bool ical_enabled { get; set; }
        public Subscription subscription { get; set; }
    }

    public class Subscription
    {
        public int workspace_id { get; set; }
        public object deleted_at { get; set; }
        public DateTime created_at { get; set; }
        public object updated_at { get; set; }
        public bool vat_valid { get; set; }
        public object vat_validated_at { get; set; }
        public object vat_invalid_accepted_at { get; set; }
        public object vat_invalid_accepted_by { get; set; }
        public string description { get; set; }
        public bool vat_applicable { get; set; }
    }

}

所以我的问题主要围绕Property1类中的Rootobject对象。我似乎无法将其正确映射,而且认为这是因为JSON序列化试图将名称Property1与某个地方的JSON中的名称匹配,但是没有名称完全是JSON。

我尝试在每个类之前添加[DataContract]并在每个属性之前添加[DataMember],但这不起作用。我还尝试在[DataMember(Name="")]声明之前添加Property1,但这也不起作用。

以下是我的序列化代码供参考:

    public static T MakeRequest<T>(string strUrl, string[][] strHeaders, string strRequestMethod = "GET") where T : class
    {
        // NOTE PARAMETERS ARE PASSED IN QUERYSTRING INSIDE URL

        try
        {
            HttpWebRequest request = WebRequest.Create(strUrl) as HttpWebRequest;
            request.Method = strRequestMethod;
            request.ContentType = "application/json";

            foreach (string[] strHeader in strHeaders)
            {
                request.Headers.Add(strHeader[0], strHeader[1]);
            }

            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                if (response.StatusCode != HttpStatusCode.OK)
                    throw new Exception(String.Format(
                    "Server error (HTTP {0}: {1}).",
                    response.StatusCode,
                    response.StatusDescription));
                DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(T));
                Stream stream = response.GetResponseStream();
                object objResponse = jsonSerializer.ReadObject(stream);
                var jsonResponse = (T)objResponse;
                response.Close();
                return jsonResponse;
            }
        }
        catch (Exception ex)
        {
            return default(T);
        }
    }

非常感谢任何帮助。

更新

所以我忘了分享的是我如何从程序中调用MakeRequest ...

        string[] strAuth = new string[] { "Authorization", $"Basic {strAuthCode}" };

        string[][] myHeaders = new string[][] { strAuth };

        TogglWorkspaceTest.Class1 WorkspaceRequest = MakeRequest<TogglWorkspaceTest.Class1>("https://www.toggl.com/api/v8/workspaces", myHeaders);

和(感谢@Plutonix)字面意思是我必须改变,在[]之后添加TogglWorkspaceTest.Class1

所以现在我有了它并且它完美地工作......

        string[] strAuth = new string[] { "Authorization", $"Basic {strAuthCode}" };

        string[][] myHeaders = new string[][] { strAuth };

        TogglWorkspaceTest.Class1[] WorkspaceRequest = MakeRequest<TogglWorkspaceTest.Class1[]>("https://www.toggl.com/api/v8/workspaces", myHeaders);

再次感谢@Plutonix!

3 个答案:

答案 0 :(得分:0)

假设您使用的是Json.NET,则可以使用DeserializeObject的通用格式:

var obj = JsonConvert.DeserializeObject<Class1>(jsonString);

答案 1 :(得分:0)

所以@Plutonix值得赞扬,但一切都在评论中,所以我在这里发布解决方案供其他人参考。

我忘记分享的是我如何从程序中调用MakeRequest ...

    string[] strAuth = new string[] { "Authorization", $"Basic {strAuthCode}" };

    string[][] myHeaders = new string[][] { strAuth };

    TogglWorkspaceTest.Class1 WorkspaceRequest = MakeRequest<TogglWorkspaceTest.Class1>("https://www.toggl.com/api/v8/workspaces", myHeaders);

和(感谢@Plutonix)字面意思是我必须改变,在[]之后添加TogglWorkspaceTest.Class1

所以现在我有了它并且它完美地工作......

    string[] strAuth = new string[] { "Authorization", $"Basic {strAuthCode}" };

    string[][] myHeaders = new string[][] { strAuth };

    TogglWorkspaceTest.Class1[] WorkspaceRequest = MakeRequest<TogglWorkspaceTest.Class1[]>("https://www.toggl.com/api/v8/workspaces", myHeaders);

再次感谢@Plutonix!

答案 2 :(得分:-1)

可能你可以使用匿名类型来反序列化json字符串。 这是一个例子 -

  

var definition = new {Name =&#34;&#34; };

     

string json1 = @&#34; {&#39; Name&#39;:&#39; James&#39;}&#34 ;; var customer1 =   JsonConvert.DeserializeAnonymousType(json1,definition);

     

Console.WriteLine(customer1.Name); //詹姆斯

     

string json2 = @&#34; {&#39;姓名&#39;:&#39; Mike&#39;}&#34 ;; var customer2 =   JsonConvert.DeserializeAnonymousType(json2,definition);

     

Console.WriteLine(customer2.Name);

以上示例的来源是 - http://www.newtonsoft.com/json/help/html/DeserializeAnonymousType.htm

以下帖子更为详细 - https://blogs.msdn.microsoft.com/alexghi/2008/12/22/using-anonymous-types-to-deserialize-json-data/