나머지 API를 빌드하기 위해 MVC 4 웹 API 및 asp.net 웹 양식 4.0을 사용하고 있습니다. 잘 작동합니다.
[HttpGet]
public HttpResponseMessage Me(string hash)
{
HttpResponseMessage httpResponseMessage;
List<Something> somethings = ...
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK,
new { result = true, somethings = somethings });
return httpResponseMessage;
}
이제 일부 속성이 직렬화되는 것을 방지해야합니다. 나는 목록에서 LINQ를 사용할 수 있고 필요한 속성 만 얻을 수 있으며 일반적으로 좋은 접근 방법이지만 현재 시나리오에서는 something
객체가 너무 복잡하고 다른 방법으로 다른 속성 집합이 필요합니다. 런타임시 각 속성을 무시하도록 표시하기가 더 쉽습니다.
그렇게 할 방법이 있습니까?
답변
ASP.NET 웹 API는 Json.Net
기본 포맷터로 사용 하므로 응용 프로그램에서 JSON 만 데이터 형식으로 사용 [JsonIgnore]
하는 경우 직렬화 속성을 무시 하는 데 사용할 수 있습니다 .
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public List<Something> Somethings { get; set; }
}
그러나이 방법은 XML 형식을 지원하지 않습니다. 그래서, 경우에 귀하의 응용 프로그램 에이 사용하는 대신, 지원 XML 포맷 이상 (또는 만 지원 XML) Json.Net
사용한다, [DataContract]
JSON과 XML을 모두 지원한다 :
[DataContract]
public class Foo
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
//Ignore by default
public List<Something> Somethings { get; set; }
}
자세한 내용은 공식 기사를 참조하십시오 .
답변
ASP.NET 웹 API 의 웹 API 문서 페이지 JSON 및 XML 직렬화에[JsonIgnore]
따르면 Json 직렬 변환기 또는 [IgnoreDataMember]
기본 XML 직렬 변환기에 사용할 수있는 특성의 직렬화를 명시 적으로 방지 할 수 있습니다 .
그러나 테스트에서 [IgnoreDataMember]
XML과 Json 요청 모두의 직렬화를 방지 한다는 것을 알았 으므로 여러 속성으로 속성을 장식하는 대신 사용하는 것이 좋습니다.
답변
기본적으로 모든 것이 직렬화 되도록 하는 대신 “선택”접근 방식을 사용할 수 있습니다. 이 시나리오에서는 지정한 속성 만 직렬화 할 수 있습니다. 당신은이 작업을 수행 DataContractAttribute
하고 DataMemberAttribute
에서 발견 들은 System.Runtime.Serialization의 네임 스페이스.
는 DataContactAttribute
클래스에 적용되고는 DataMemberAttribute
당신이 직렬화 할 각 멤버에 적용된다 :
[DataContract]
public class MyClass {
[DataMember]
public int Id { get; set;} // Serialized
[DataMember]
public string Name { get; set; } // Serialized
public string DontExposeMe { get; set; } // Will not be serialized
}
감히 나는 이것이 직렬화를 통해 무엇을 할 것인지 아닌지를 분명하게 결정하도록 강요하기 때문에 더 나은 접근 방법이라고 말합니다. 또한 JSON.net에 의존하지 않고 모델 클래스를 JSON.net에 의존하지 않고 모델 클래스가 프로젝트에 살 수 있습니다.
답변
이것은 나를 위해 일했습니다 : 문자열 배열 유형의 AllowList라는 공용 속성이있는 사용자 지정 계약 해결 프로그램을 만드십시오. 조치에서 조치를 리턴해야하는 항목에 따라 해당 특성을 수정하십시오.
1. 사용자 지정 계약 해결 프로그램을 만듭니다.
public class PublicDomainJsonContractResolverOptIn : DefaultContractResolver
{
public string[] AllowList { get; set; }
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
properties = properties.Where(p => AllowList.Contains(p.PropertyName)).ToList();
return properties;
}
}
2. 실제 사용자 지정 계약 해결 프로그램 사용
[HttpGet]
public BinaryImage Single(int key)
{
//limit properties that are sent on wire for this request specifically
var contractResolver = Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver as PublicDomainJsonContractResolverOptIn;
if (contractResolver != null)
contractResolver.AllowList = new string[] { "Id", "Bytes", "MimeType", "Width", "Height" };
BinaryImage image = new BinaryImage { Id = 1 };
//etc. etc.
return image;
}
이 접근 방식을 통해 클래스 정의를 수정하는 대신 특정 요청에 대해 허용 / 금지 할 수있었습니다. XML 직렬화가 필요하지 않은 App_Start\WebApiConfig.cs
경우 클라이언트 에서 XML 직렬화를 해제해야 합니다. 그렇지 않으면 클라이언트가 json 대신 xml을 요청하는 경우 API에서 차단 된 속성을 반환합니다.
//remove xml serialization
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
답변
나는 당신이 원하는 것을 성취하는 두 가지 방법을 보여줄 것입니다 :
첫 번째 방법 : 필드가 null 인 경우 해당 필드의 직렬화를 건너 뛰려면 JsonProperty 속성으로 필드를 장식하십시오.
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public List<Something> Somethings { get; set; }
}
두 번째 방법 : 복잡한 시나리오와 협상하는 경우 특정 논리에 따라 해당 필드의 직렬화를 건너 뛰기 위해 웹 API 규칙 ( “ShouldSerialize”)을 사용할 수 있습니다.
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public List<Something> Somethings { get; set; }
public bool ShouldSerializeSomethings() {
var resultOfSomeLogic = false;
return resultOfSomeLogic;
}
}
WebApi는 JSON.Net을 사용하고 직렬화에 반영을 사용하므로, 예를 들어 ShouldSerializeFieldX () 메소드를 감지하면 이름이 FieldX 인 필드가 직렬화되지 않습니다.
답변
나는 게임에 늦었지만 익명의 물건이 트릭을 할 것입니다.
[HttpGet]
public HttpResponseMessage Me(string hash)
{
HttpResponseMessage httpResponseMessage;
List<Something> somethings = ...
var returnObjects = somethings.Select(x => new {
Id = x.Id,
OtherField = x.OtherField
});
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK,
new { result = true, somethings = returnObjects });
return httpResponseMessage;
}
답변
IgnoreDataMember
속성을 사용해보십시오
public class Foo
{
[IgnoreDataMember]
public int Id { get; set; }
public string Name { get; set; }
}