การปิด JsonProperty Required.Always โดยไม่ต้องแก้ไขคลาส (Json.NET)

wk
1 min readNov 28, 2018

ตัวอย่าง มีคลาส Student ประกอบด้วยสอง Property คือ Id และ Name โดย Name มีการประกาศ Attribute JsonProperty ไว้ดังนี้

class Student {
public string Id { set; get; }
[JsonProperty(Required = Required.Always)]
public string Name { set; get; }
}

ในการกรณีที่ต้องการ De-serialize Json ที่มีข้อมูลไม่สมบูรณ์ เช่น ไม่มี Name

{
"id": 1
}

เมื่อใช้ฟังก์ชัน JsonConvet.DeserializeObject<Student>(json) จะเกิด Error ดังนี้

Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Required property 'Name' not found in JSON

ปัญหาเกิดจาก Attribute [JsonProperty(Required = Required.Always)] ที่ระบุว่าจะต้องมีข้อมูล Name เสมอ ดังนี้ Json ในกรณีนี้จะไม่สามารถ De-serialize เป็น Student ได้ ถึงแม้ไม่ต้องการข้อมูล Name ไปใช้ก็ตาม

วิธีแก้ โดยไม่ต้องลบ [JsonProperty(Required = Required.Always)] ออกจากคลาส คือ เขียน ContractResolver ขึ้นใหม่ เช่น IgnoreContractResolver

public class IgnoreContractResolver : DefaultContractResolver {
private readonly string[] excludes;
public IgnoreContractResolver(string[] names) {
excludes = names;
}
protected override IList<JsonProperty>
CreateProperties(Type type, MemberSerialization ms) {
return base.CreateProperties(type, ms)
.Where(p => !excludes.Contains(p.PropertyName))
.ToList();
}
}

โดยเรียกใช้ IgnoreContractResolver ผ่าน JsonSerializerSettings ดังนี้

class Program {
static void Main(string[] args) {
var settings = new JsonSerializerSettings();
settings.ContractResolver =
new IgnoreContractResolver(new[] { "Name" });
var json = @"
{
""id"": ""1""
}
";
var obj = JsonConvert
.DeserializeObject<Student>(json, settings);
}
}

--

--

No responses yet