programing

JsonConvert 사용.Deserialize Object를 사용하여 Json을 C# POCO 클래스로 역직렬화합니다.

testmans 2023. 3. 16. 21:14
반응형

JsonConvert 사용.Deserialize Object를 사용하여 Json을 C# POCO 클래스로 역직렬화합니다.

여기 간단한 것이 있습니다.UserPOCO 클래스:

/// <summary>
/// The User class represents a Coderwall User.
/// </summary>
public class User
{
    /// <summary>
    /// A User's username. eg: "sergiotapia, mrkibbles, matumbo"
    /// </summary>
    public string Username { get; set; }

    /// <summary>
    /// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan"
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// A User's location. eh: "Bolivia, USA, France, Italy"
    /// </summary>
    public string Location { get; set; }

    public int Endorsements { get; set; } //Todo.
    public string Team { get; set; } //Todo.

    /// <summary>
    /// A collection of the User's linked accounts.
    /// </summary>
    public List<Account> Accounts { get; set; }

    /// <summary>
    /// A collection of the User's awarded badges.
    /// </summary>
    public List<Badge> Badges { get; set; }

}

JSON 응답을 디시리얼라이즈하기 위해 사용하는 방법User오브젝트(실제 JSON 콜은 여기에 있습니다):

private User LoadUserFromJson(string response)
{
    var outObject = JsonConvert.DeserializeObject<User>(response);
    return outObject;
}

그러면 예외가 발생합니다.

현재 JSON 개체(예: {"name":"value"})를 '시스템' 유형으로 역직렬화할 수 없습니다.컬렉션포괄적인.리스트 1 [Coderwall DotNet]API.모델어카운트]'는 타입이 올바르게 역직렬화하려면 JSON 배열(예: [1, 2, 3])이 필요하기 때문입니다.

이 오류를 수정하려면 JSON을 JSON 배열(예: [1, 2, 3])로 변경하거나 일반이 되도록 역직렬화 유형을 변경합니다.JSON 개체에서 역직렬화할 수 있는 NET 유형(예: 정수, 배열 또는 목록과 같은 수집 유형이 아님)Json Object Attribute를 유형에 추가하여 JSON 개체에서 강제로 역직렬화할 수도 있습니다.경로 'accounts.github', 줄 1, 위치 129.

이 Deserialize Object 메서드를 사용해 본 적이 없기 때문에, 저는 여기서 꼼짝할 수 없습니다.

POCO 클래스의 속성명이 JSON 응답의 이름과 동일한지 확인했습니다.

JSON을 이 POCO 클래스로 역직렬화하려면 어떻게 해야 하나요?

여기 작업 예가 있습니다.

요점은 다음과 같습니다.

  • 선언Accounts
  • 사용방법JsonProperty기여하다

.

using (WebClient wc = new WebClient())
{
    var json = wc.DownloadString("http://coderwall.com/mdeiters.json");
    var user = JsonConvert.DeserializeObject<User>(json);
}

-

public class User
{
    /// <summary>
    /// A User's username. eg: "sergiotapia, mrkibbles, matumbo"
    /// </summary>
    [JsonProperty("username")]
    public string Username { get; set; }

    /// <summary>
    /// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan"
    /// </summary>
    [JsonProperty("name")]
    public string Name { get; set; }

    /// <summary>
    /// A User's location. eh: "Bolivia, USA, France, Italy"
    /// </summary>
    [JsonProperty("location")]
    public string Location { get; set; }

    [JsonProperty("endorsements")]
    public int Endorsements { get; set; } //Todo.

    [JsonProperty("team")]
    public string Team { get; set; } //Todo.

    /// <summary>
    /// A collection of the User's linked accounts.
    /// </summary>
    [JsonProperty("accounts")]
    public Account Accounts { get; set; }

    /// <summary>
    /// A collection of the User's awarded badges.
    /// </summary>
    [JsonProperty("badges")]
    public List<Badge> Badges { get; set; }
}

public class Account
{
    public string github;
}

public class Badge
{
    [JsonProperty("name")]
    public string Name;
    [JsonProperty("description")]
    public string Description;
    [JsonProperty("created")]
    public string Created;
    [JsonProperty("badge")]
    public string BadgeUrl;
}

카멜 캐시된 JSON 스트링을 파스칼 캐시된 POCO 오브젝트로 역직렬화하는 다른 보다 합리화된 접근법은 Camel Case Property Names Contract Resolver를 사용하는 것입니다.

뉴턴소프트의 일부야Json.시리얼라이제이션 네임스페이스이 접근법에서는 JSON 객체와 POCO의 유일한 차이점은 속성 이름의 대문자화에 있다고 가정합니다.속성 이름의 철자가 다를 경우 JsonProperty 속성을 사용하여 속성 이름을 매핑해야 합니다.

using Newtonsoft.Json; 
using Newtonsoft.Json.Serialization;

. . .

private User LoadUserFromJson(string response) 
{
    JsonSerializerSettings serSettings = new JsonSerializerSettings();
    serSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    User outObject = JsonConvert.DeserializeObject<User>(jsonValue, serSettings);

    return outObject; 
}

계정 속성은 다음과 같이 정의됩니다.

"accounts":{"github":"sergiotapia"}

귀사의 POCO에는 다음과 같이 기술되어 있습니다.

public List<Account> Accounts { get; set; }

다음 Json을 사용해 보십시오.

"accounts":[{"github":"sergiotapia"}]

목록에 매핑되는 항목의 배열은 항상 대괄호로 둘러싸여 있습니다.

편집: 계정 Poco는 다음과 같습니다.

class Account {
    public string github { get; set; }
}

다른 재산도 있을 수 있어요

편집 2: 어레이를 사용하지 않으려면 다음과 같이 속성을 사용합니다.

public Account Accounts { get; set; }

제가 첫 번째 편집에 올린 샘플 수업 같은 걸로요.

해서 만들 수 요.JsonConverter질문 내용과 유사한 예는 여기를 참조하십시오.

승인된 답변에 따라 JSON 텍스트샘플이 있는 경우 이 변환기에 연결하고 옵션을 선택하여 C# 코드를 생성할 수 있습니다.

런타임에 유형을 모를 경우 이 항목이 적합한 것 같습니다.

전달된 오브젝트에 json을 동적으로 역직렬화합니다.c#

to fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the
deserialized type so that it is a normal .NET type (e.g. not a primitive type like
integer, not a collection type like an array or List) that can be deserialized from a
JSON object.`

메시지 전체가 List 객체에 시리얼화할 수 있음을 나타내지만 입력은 JSON 목록이어야 합니다.즉, JSON에는 다음 명령어가 포함되어 있어야 합니다.

"accounts" : [{<AccountObjectData}, {<AccountObjectData>}...],

여기서 AccountObject data는 계정 개체 또는 배지 개체를 나타내는 JSON입니다.

현재 얻을 수 있는 것은

"accounts":{"github":"sergiotapia"}

여기서 accounts는 JSON 오브젝트(괄호로 둘러싸여 있음)의 배열이 아닌 JSON 오브젝트(괄호로 둘러싸여 있음)입니다.해라

"accounts" : [{"github":"sergiotapia"}]

내가 생각한 건 정확히 그게 아니었어.실행 시에만 알 수 있는 범용 유형이 있는 경우 어떻게 해야 합니까?

public MyDTO toObject() {
  try {
    var methodInfo = MethodBase.GetCurrentMethod();
    if (methodInfo.DeclaringType != null) {
      var fullName = methodInfo.DeclaringType.FullName + "." + this.dtoName;
      Type type = Type.GetType(fullName);
      if (type != null) {
        var obj = JsonConvert.DeserializeObject(payload);
      //var obj = JsonConvert.DeserializeObject<type.MemberType.GetType()>(payload);  // <--- type ?????
          ...
      }
    }

    // Example for java..   Convert this to C#
    return JSONUtil.fromJSON(payload, Class.forName(dtoName, false, getClass().getClassLoader()));
  } catch (Exception ex) {
    throw new ReflectInsightException(MethodBase.GetCurrentMethod().Name, ex);
  }
}

늦어질 수도 있지만 QuickType을 사용하는 것이 가장 쉬운 방법입니다.

https://app.quicktype.io/

이 문제를 안고 있는 사람에게는 json 값이 제대로 보이지 않았습니다.https://jsonutils.com/ 에서 생성해야 할 클래스를 확인하고 코드의 json을 읽으면 그 중 하나만 반환할 수 있습니다.

예를 들어, 나는 책 목록 객체가 필요했기 때문에 내 코드는 하나만 읽어야 한다.

res = await response.Content.ReadAsAsync<BookList>();

북리스트가 어떻게 생겼는지

    public class BookList
    {

        [JsonProperty("data")]
        public IList<Datum> Data { get; set; }
     }

그리고 그 목록에는 변환자가 데이텀(책만)이라고 이름 붙인 더 작은 책 클래스가 있다.

    public class Datum
    {

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

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

다시 말씀드리지만, 의문이 있으시면 https://jsonutils.com/를 방문해주세요.

언급URL : https://stackoverflow.com/questions/11126242/using-jsonconvert-deserializeobject-to-deserialize-json-to-a-c-sharp-poco-class

반응형