ASP.NET WebAPI(반) 서열화[serializable Attribute]로 장식된 클래스의 구덩이

2945 단어
문제점 발견
ASP에서.NET WebAPI 항목에는 다음과 같은 ViewModel 클래스가 있습니다.
[Serializable]
class Product
{
    public int Id { get; set; }
    public decimal Price { get; set; }
    public DateTime ProductDate { get; set; }
}

Controller 및 Action 코드는 다음과 같습니다.
public class ProductController : ApiController
{
    public Product Get(int id)
    {
        return new Product()
        {
            Id = 1,
            Price = 12.9m,
            ProductDate = new DateTime(1992, 1, 1)
        };
    }
}

클라이언트가 리소스를 요청한 결과: http://localhost:5000/api/product/1 WebAPI가 다음과 같은 JSON을 반환했습니다.
{
  "k__BackingField": 1,
  "k__BackingField": 12.9,
  "k__BackingField": "1992-01-01T00:00:00"
}

우리는 자동 속성이 정의된 필드는 없지만 C#컴파일러가 해당하는 개인 필드를 생성할 수 있다는 것을 알고 있다private int k__BackingField.우리는 WebAPI 서열화할 때 속성 이름을 JSON의 키로 삼기를 희망하지만, 여기서 WebAPI 서열화는 컴파일러가 생성한 개인 필드이기 때문에 우리의 요구에 부합되지 않습니다.
이상한 점은 단독으로 Json을 쓰면.NET 라이브러리를 서열화하면 다음과 같은 JSON을 얻을 수 있습니다.
{
  "Id": 1,
  "Price": 12.9,
  "ProductDate": "1992-01-01T00:00:00"
}

원인을 찾다
Google은 원래 Serializable Attribute와 관련이 있습니다.제이슨에서.NET 4.5 Release 2 릴리즈부터 다음과 같은 새로운 기능이 추가되었습니다.
유형에 Serializable Attribute가 검출되면 해당 유형의 모든 개인/공개 필드를 서열화하고 속성을 무시합니다.이 새로운 기능을 원하지 않으면, 클래스에 Json Object Attribute를 적용하거나, 전역적으로Default Contract Resolver의 Ignore Serializable Attribute를true로 설정할 수 있습니다.release 3 버전부터 IgnoreSerializable Attribute는 기본값true입니다.
ASP.NET WebAPI는 Json에 의존합니다.NET, 그러나 Ignore Serializable Attribute를false로 설정합니다. 즉, Serializable Attribute를 무시하지 않기 때문에 클래스가 [serializable Attribute]로 수식되면 필드만 서열화하고 속성을 무시합니다. 따라서 자동 속성을 사용할 때 출력하는 것은 컴파일러가 자동으로 생성한 필드 이름입니다.
문제를 해결하다
문제의 원인을 알게 되면 다음과 같은 방법으로 해결할 수 있다.
  • [Serializable]
  • 제거
  • 응용[JsonObjectAttribute]
  • IgnoreSerializable Attribute
  • 설정
    가장 간단한 방법은 [serializable]를 제거하는 것이다. 만약 어떤 원인으로 제거할 수 없다면 다른 두 가지 방법을 사용할 수 있다.
    JsonObjectAttribute 적용
    [Newtonsoft.Json.JsonObject]
    [System.Serializable]
    class Product
    {
        public int Id { get; set; }
        public decimal Price { get; set; }
        public DateTime ProductDate { get; set; }
    }

    IgnoreSerializable Attribute 설정
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            //        .........
    
            //   SerializerSettings        IgnoreSerializableAttribute = true
            config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
        }
    }

    참조: Json.NET 4.5 Release 2 – Serializable support and bug fixesWhy won't Web API deserialize this but JSON.Net will?
    전재 대상:https://www.cnblogs.com/songxingzheng/p/6482431.html

    좋은 웹페이지 즐겨찾기