JSON POST 调用时的自引用循环
JSON Self referencing loop on POST call
我正在尝试通过 JsonApi 发送 POST 调用,例如:
{
"data": {
"attributes": {
"booked_by_patient": true,
"class": "PUBLIC",
"description": "description",
"dtend": "2022-03-16T10:30:00+01:00",
"dtstamp": "2022-03-16T10:01:17+01:00",
"dtstart": "2022-03-16T10:00:00+01:00",
"location": "1231, 31311 3131",
"new_patient": true,
"referral_source": "",
"status": "CONFIRMED",
"summary": "summary",
"text": "",
"transp": "OPAQUE",
"uid": null,
"first_name": "name",
"last_name": "last_name",
"e_mail_address": "email@domain.com",
"phone_number_cell": "+467325324563252"
},
"relationships": {
"clinic": {
"data": {
"id": "2312",
"type": "Pizza-clinics"
}
},
"organizer": {
"data": {
"id": "5553",
"type": "Pizza-caregivers"
}
},
"procedure": {
"data": {
"id": "1",
"type": "Pizza-procedure"
}
}
},
"type": "Pizza-bookings"
},
"include": "booking_attendees.patient"
}
但是对于初学者来说,我收到一个错误“检测到类型为 'SDKs.Pizza.Model.Clinics' 的 属性 'data' 的自引用循环。路径 'data.clinic.data'.
根据我收到的另一个建议,我需要在某些模型上添加 [JsonIgnore] 装饰器,我做了以下操作:(装饰器在最后 3 个对象上)
public class BookingRequest
{
// public string Id { get; set; }
public string? Uid { get; set; } = null;
public string Type { get; } = "pizza_bookings";
public bool BookedByPatient { get; set; } = true;
public string Class { get; set; } = "PUBLIC";
public string Description { get; set; } = null!;
[JsonProperty(PropertyName = "dtstart")]
public DateTimeOffset Start { get; set; }
[JsonProperty(PropertyName = "dtend")]
public DateTimeOffset End { get; set; }
[JsonProperty(PropertyName = "dtstamp")]
public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.UtcNow;
public string EMailAddress { get; set; } = null!;
public string FirstName { get; set; } = null!;
public string LastName { get; set; } = null!;
public string Location { get; set; } = null!;
public bool NewPatient { get; set; } = true;
public string PhoneNumberCell { get; set; } = null!;
public string ReferralSource { get; set; } = "source";
public string Status { get; set; } = "CONFIRMED";
public string Summary { get; set; } = "";
public string Text { get; set; } = "";
public string? Transp { get; set; } = "OPAQUE";
[JsonIgnore]
public Relationship<Clinics> Clinic { get; set; } = null!;
[JsonIgnore]
public Relationship<Caregivers> Organizer { get; set; } = null!;
[JsonIgnore]
public Relationship<Procedures> Procedure { get; set; } = null!;
}
我目前的POST调用如下:
public async Task<Booking?> CreateBookingAsync(string clinicId, string caregiverId, string procedureId, string ssn,
DateTimeOffset start, DateTimeOffset end)
{
var uri = "api/pizza-bookings".AddQueryParams(new Dictionary<string, string?> {
["caregiver_id"] = caregiverId,
["patient_personal_id"] = swedishPersonalIdentityNumber
}
);
var body = new DocumentRoot<BookingRequest>();
var clinic = new Relationship<Clinics>() {Data = new Clinics() {Id = clinicId}};
var organizer = new Relationship<Caregivers>() {Data = new Caregivers() {Id = caregiverId}};
var procedure = new Relationship<Procedures>() {Data = new Procedures() {Id = procedureId}};
body.Data = new BookingRequest() {
Start = start,
End = end,
EMailAddress = "email@domain.com",
PhoneNumberCell = "123-456-789",
FirstName = "first-name",
LastName = "last-name",
Clinic = clinic,
Organizer = organizer,
Procedure = procedure
};
return await _http.SendInternalAsync<DocumentRoot<BookingRequest>, Booking>(HttpMethod.Post, uri, body, new Dictionary<string, string>());
}
我在这里遇到的问题是,如果我添加 jsonIgnore,代码会运行,但是 JSON 我从 Fiddler 捕获的内容如下:
{
"data": {
"type": "pizza_bookings",
"bookedByPatient": true,
"class": "PUBLIC",
"dtstart": "2022-03-17T08:56:00+01:00",
"dtend": "2022-03-17T09:26:00+01:00",
"dtstamp": "2022-03-17T07:56:48.3039336+00:00",
"eMailAddress": "email@domain.com",
"firstName": "first-name",
"lastName": "last-name",
"newPatient": true,
"phoneNumberCell": "123-456-789",
"referralSource": "source",
"status": "CONFIRMED",
"summary": "",
"text": "",
"transp": "OPAQUE",
"clinic": {
"data": {}
},
"organizer": {
"data": {}
},
"procedure": {
"data": {}
}
}
}
您可以在使用 ReferenceLoopHandling.Ignore
序列化时忽略 self-referencing 循环,如果对象是其自身的子对象,则不会序列化该对象。您可以通过在序列化程序设置中添加它来使用它:
JsonConvert.SerializeObject(body.Data, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore});
我正在尝试通过 JsonApi 发送 POST 调用,例如:
{
"data": {
"attributes": {
"booked_by_patient": true,
"class": "PUBLIC",
"description": "description",
"dtend": "2022-03-16T10:30:00+01:00",
"dtstamp": "2022-03-16T10:01:17+01:00",
"dtstart": "2022-03-16T10:00:00+01:00",
"location": "1231, 31311 3131",
"new_patient": true,
"referral_source": "",
"status": "CONFIRMED",
"summary": "summary",
"text": "",
"transp": "OPAQUE",
"uid": null,
"first_name": "name",
"last_name": "last_name",
"e_mail_address": "email@domain.com",
"phone_number_cell": "+467325324563252"
},
"relationships": {
"clinic": {
"data": {
"id": "2312",
"type": "Pizza-clinics"
}
},
"organizer": {
"data": {
"id": "5553",
"type": "Pizza-caregivers"
}
},
"procedure": {
"data": {
"id": "1",
"type": "Pizza-procedure"
}
}
},
"type": "Pizza-bookings"
},
"include": "booking_attendees.patient"
}
但是对于初学者来说,我收到一个错误“检测到类型为 'SDKs.Pizza.Model.Clinics' 的 属性 'data' 的自引用循环。路径 'data.clinic.data'.
根据我收到的另一个建议,我需要在某些模型上添加 [JsonIgnore] 装饰器,我做了以下操作:(装饰器在最后 3 个对象上)
public class BookingRequest
{
// public string Id { get; set; }
public string? Uid { get; set; } = null;
public string Type { get; } = "pizza_bookings";
public bool BookedByPatient { get; set; } = true;
public string Class { get; set; } = "PUBLIC";
public string Description { get; set; } = null!;
[JsonProperty(PropertyName = "dtstart")]
public DateTimeOffset Start { get; set; }
[JsonProperty(PropertyName = "dtend")]
public DateTimeOffset End { get; set; }
[JsonProperty(PropertyName = "dtstamp")]
public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.UtcNow;
public string EMailAddress { get; set; } = null!;
public string FirstName { get; set; } = null!;
public string LastName { get; set; } = null!;
public string Location { get; set; } = null!;
public bool NewPatient { get; set; } = true;
public string PhoneNumberCell { get; set; } = null!;
public string ReferralSource { get; set; } = "source";
public string Status { get; set; } = "CONFIRMED";
public string Summary { get; set; } = "";
public string Text { get; set; } = "";
public string? Transp { get; set; } = "OPAQUE";
[JsonIgnore]
public Relationship<Clinics> Clinic { get; set; } = null!;
[JsonIgnore]
public Relationship<Caregivers> Organizer { get; set; } = null!;
[JsonIgnore]
public Relationship<Procedures> Procedure { get; set; } = null!;
}
我目前的POST调用如下:
public async Task<Booking?> CreateBookingAsync(string clinicId, string caregiverId, string procedureId, string ssn,
DateTimeOffset start, DateTimeOffset end)
{
var uri = "api/pizza-bookings".AddQueryParams(new Dictionary<string, string?> {
["caregiver_id"] = caregiverId,
["patient_personal_id"] = swedishPersonalIdentityNumber
}
);
var body = new DocumentRoot<BookingRequest>();
var clinic = new Relationship<Clinics>() {Data = new Clinics() {Id = clinicId}};
var organizer = new Relationship<Caregivers>() {Data = new Caregivers() {Id = caregiverId}};
var procedure = new Relationship<Procedures>() {Data = new Procedures() {Id = procedureId}};
body.Data = new BookingRequest() {
Start = start,
End = end,
EMailAddress = "email@domain.com",
PhoneNumberCell = "123-456-789",
FirstName = "first-name",
LastName = "last-name",
Clinic = clinic,
Organizer = organizer,
Procedure = procedure
};
return await _http.SendInternalAsync<DocumentRoot<BookingRequest>, Booking>(HttpMethod.Post, uri, body, new Dictionary<string, string>());
}
我在这里遇到的问题是,如果我添加 jsonIgnore,代码会运行,但是 JSON 我从 Fiddler 捕获的内容如下:
{
"data": {
"type": "pizza_bookings",
"bookedByPatient": true,
"class": "PUBLIC",
"dtstart": "2022-03-17T08:56:00+01:00",
"dtend": "2022-03-17T09:26:00+01:00",
"dtstamp": "2022-03-17T07:56:48.3039336+00:00",
"eMailAddress": "email@domain.com",
"firstName": "first-name",
"lastName": "last-name",
"newPatient": true,
"phoneNumberCell": "123-456-789",
"referralSource": "source",
"status": "CONFIRMED",
"summary": "",
"text": "",
"transp": "OPAQUE",
"clinic": {
"data": {}
},
"organizer": {
"data": {}
},
"procedure": {
"data": {}
}
}
}
您可以在使用 ReferenceLoopHandling.Ignore
序列化时忽略 self-referencing 循环,如果对象是其自身的子对象,则不会序列化该对象。您可以通过在序列化程序设置中添加它来使用它:
JsonConvert.SerializeObject(body.Data, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore});