C# 通过.NET Core Web API在实体框架Core中修补实体和相关实体
我有一个用.NETCore编写的Web API,它使用EFCore管理postgresql数据库的插入和查询。该API对于现有实体的插入和查询非常有效,但我在解决如何进行部分“补丁”更新方面遇到了困难。客户机希望能够只传递他们希望更新的属性。因此,完整的客户JSON负载可能如下所示:C# 通过.NET Core Web API在实体框架Core中修补实体和相关实体,c#,entity-framework-core,npgsql,http-patch,C#,Entity Framework Core,Npgsql,Http Patch,我有一个用.NETCore编写的Web API,它使用EFCore管理postgresql数据库的插入和查询。该API对于现有实体的插入和查询非常有效,但我在解决如何进行部分“补丁”更新方面遇到了困难。客户机希望能够只传递他们希望更新的属性。因此,完整的客户JSON负载可能如下所示: { "customer": { "identification": { "membership_number&quo
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au",
"loyalty_db_id": "4638092"
},
"name": {
"title": "Ms",
"first_name": "tx2bxtqoa",
"surname": "oe6qoto"
},
"date_of_birth": "1980-12-24T00:00:00",
"gender": "F",
"customer_type": "3",
"home_store_id": "777",
"home_store_updated": "1980-12-24T00:00:00",
"store_joined_id": "274",
"store_joined_date": "1980-12-24T00:00:00",
"status_reason": null,
"status": "50",
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": true,
"updating_store": null
}
],
"marketing_preferences": [],
"address": {
"address_line_1": "something stree",
"address_line_2": "Snyder",
"postcode": "3030"
},
"external_cards": [
{
"updating_store": null,
"card_type": "PY",
"card_design": null,
"card_number": "2701138910268",
"status": "ACTIVE",
"physical_print": false
}
]
}
}
public class CustomerPayload
{
public Identification Identification { get; set; }
[JsonProperty("contact_information")]
public ContactInfo[] ContactInformation { get; set; }
}
public class ContactInfo
{
public bool Validated { get; set; }
}
public class Identification
{
[JsonProperty("membership_number")]
public string MembershipNumber { get; set; }
public string SomePropertyNotInPayload { get; set; }
}
public class PartialCustomerPayloadWrapper
{
public JObject Customer { get; set; }
}
但是客户端希望传入一个有效负载,如:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au"
},
"address": {
"address_line_1": "something stree"
},
}
}
只更新地址行1
属性。其余字段将保持原样。不幸的是,因为我将JSON转换为CustomerPayload
对象,然后CustomerPayload
对象转换为Customer
对象(以及相关实体),如果未传递属性,则将其设置为NULL
这意味着,当我在EF Core中使用SetValues
复制属性时,未提供的属性将设置为NULL,然后在数据库中更新为NULL。除了要求客户机传递所有属性,只传递保持不变的属性的现有值之外,我不确定如何处理这个问题
因此,一旦传入的JSON转换为CustomerPayload
(并验证属性),我就使用下面的代码将CustomerPayload
转换为Customer
:
public Customer Convert(CustomerPayload source)
{
Customer customer = new Customer
{
McaId = source.RequestCustomer.Identification.MembershipNumber,
BusinessPartnerId = source.RequestCustomer.Identification.BusinessPartnerId,
Status = source.RequestCustomer.Status,
StatusReason = source.RequestCustomer.StatusReason,
LoyaltyDbId = source.RequestCustomer.Identification.LoyaltyDbId,
Gender = source.RequestCustomer.Gender,
DateOfBirth = source.RequestCustomer.DateOfBirth,
CustomerType = source.RequestCustomer.CustomerType,
HomeStoreId = source.RequestCustomer.HomeStoreId,
HomeStoreUpdated = source.RequestCustomer.HomeStoreUpdated,
StoreJoined = source.RequestCustomer.StoreJoinedId,
CreatedDate = Functions.GenerateDateTimeByLocale(),
UpdatedBy = Functions.DbUser
};
if (source.RequestCustomer.Name != null)
{
customer.Title = source.RequestCustomer.Name.Title;
customer.FirstName = source.RequestCustomer.Name.FirstName;
customer.LastName = source.RequestCustomer.Name.Surname;
}
if (source.RequestCustomer.Address != null)
{
customer.Address.Add(new Address
{
AddressType = source.RequestCustomer.Address.AddressType,
AddressLine1 = source.RequestCustomer.Address.AddressLine1,
AddressLine2 = source.RequestCustomer.Address.AddressLine2,
Suburb = source.RequestCustomer.Address.Suburb,
Postcode = source.RequestCustomer.Address.Postcode,
Region = source.RequestCustomer.Address.State,
Country = source.RequestCustomer.Address.Country,
CreatedDate = Functions.GenerateDateTimeByLocale(),
UpdatedBy = Functions.DbUser,
UpdatingStore = source.RequestCustomer.Address.UpdatingStore,
AddressValidated = source.RequestCustomer.Address.AddressValidated,
AddressUndeliverable = source.RequestCustomer.Address.AddressUndeliverable
});
}
if (source.RequestCustomer.MarketingPreferences != null)
{
customer.MarketingPreferences = source.RequestCustomer.MarketingPreferences
.Select(x => new MarketingPreferences()
{
ChannelId = x.Channel,
OptIn = x.OptIn,
ValidFromDate = x.ValidFromDate,
UpdatedBy = Functions.DbUser,
CreatedDate = Functions.GenerateDateTimeByLocale(),
UpdatingStore = x.UpdatingStore,
ContentTypePreferences = (from c in x.ContentTypePreferences
where x.ContentTypePreferences != null
select new ContentTypePreferences
{
TypeId = c.Type,
OptIn = c.OptIn,
ValidFromDate = c.ValidFromDate,
ChannelId = x.Channel //TODO: Check if this will just naturally be passed in JSON so can use c. instead of x.)
}).ToList(),
})
.ToList();
}
if (source.RequestCustomer.ContactInformation != null)
{
// Validate email if present
var emails = (from e in source.RequestCustomer.ContactInformation
where e.ContactType.ToUpper() == ContactInformation.ContactTypes.Email && e.ContactValue != null
select e.ContactValue);
foreach (var email in emails)
{
Console.WriteLine($"Validating email {email}");
if (!IsValidEmail(email))
{
throw new Exception($"Email address {email} is not valid.");
}
}
customer.ContactInformation = source.RequestCustomer.ContactInformation
.Select(x => new ContactInformation()
{
ContactType = x.ContactType,
ContactValue = x.ContactValue,
CreatedDate = Functions.GenerateDateTimeByLocale(),
UpdatedBy = Functions.DbUser,
Validated = x.Validated,
UpdatingStore = x.UpdatingStore
})
.ToList();
}
if (source.RequestCustomer.ExternalCards != null)
{
customer.ExternalCards = source.RequestCustomer.ExternalCards
.Select(x => new ExternalCards()
{
CardNumber = x.CardNumber,
CardStatus = x.Status.ToUpper(),
CardDesign = x.CardDesign,
CardType = x.CardType,
UpdatingStore = x.UpdatingStore,
UpdatedBy = Functions.DbUser
})
.ToList();
}
Console.WriteLine($"{customer.ToJson()}");
return customer;
}
然后我使用下面的方法进行更新。我现在有一个最好的折衷办法,就是他们可以省略某些部分(比如地址,或者联系人信息中的任何内容等),并且不会更新任何内容,但是他们希望能够完全灵活地传递各个属性,我想提供这一点。我如何重新构造它,以便如果它们不传递客户或相关实体(地址等)的特定属性,它们在EF Core生成的SetValues或update语句中被忽略
public static CustomerPayload UpdateCustomerRecord(CustomerPayload customerPayload)
{
try
{
var updateCustomer = customerPayload.Convert(customerPayload);
var customer = GetCustomerByCardNumber(updateCustomer.ExternalCards.First().CardNumber);
Console.WriteLine($"Existing customer {customer.McaId} will be updated from incoming customer {updateCustomer.McaId}");
using (var loyalty = new loyaltyContext())
{
loyalty.Attach(customer);
// If any address is provided
if (updateCustomer.Address.Any())
{
Console.WriteLine($"Update customer has an address");
foreach (Address a in updateCustomer.Address)
{
Console.WriteLine($"Address of type {a.AddressType}");
if (customer.Address.Any(x => x.AddressType == a.AddressType))
{
Console.WriteLine($"Customer already has an address of this type, so it is updated.");
a.AddressInternalId = customer.Address.First(x => x.AddressType == a.AddressType).AddressInternalId;
a.CustomerInternalId = customer.Address.First(x => x.AddressType == a.AddressType).CustomerInternalId;
a.CreatedDate = customer.Address.First(x => x.AddressType == a.AddressType).CreatedDate;
a.UpdatedDate = Functions.GenerateDateTimeByLocale();
a.UpdatedBy = Functions.DbUser;
loyalty.Entry(customer.Address.First(x => x.AddressType == a.AddressType)).CurrentValues.SetValues(a);
}
else
{
Console.WriteLine($"Customer does not have an address of this type, so it is inserted.");
customer.AddAddressToCustomer(a);
}
}
}
// We want to update contact information
if (updateCustomer.ContactInformation.Any())
{
Console.WriteLine($"Some contact information has been provided to update");
foreach (var c in updateCustomer.ContactInformation)
{
Console.WriteLine($"Assessing contact information {c.ContactValue} of type {c.ContactType}");
if (customer.ContactInformation.Any(ci => ci.ContactType == c.ContactType))
{
Console.WriteLine($"The customer already has a contact type of {c.ContactType}");
// we have an existing contact of this type so update
var existContact = (from cn in customer.ContactInformation
where cn.ContactType == c.ContactType
select cn).Single();
Console.WriteLine($"Existing contact id is {existContact.ContactInternalId} with value {existContact.ContactValue} from customer id {existContact.CustomerInternalId} which should match db customer {customer.CustomerInternalId}");
// Link the incoming contact to the existing contact by Id
c.CustomerInternalId = existContact.CustomerInternalId;
c.ContactInternalId = existContact.ContactInternalId;
// Set the update date time to now
c.UpdatedDate = Functions.GenerateDateTimeByLocale();
c.UpdatedBy = Functions.DbUser;
c.CreatedDate = existContact.CreatedDate;
loyalty.Entry(existContact).CurrentValues.SetValues(c);
}
else
{
Console.WriteLine($"There is no existing type of {c.ContactType} so creating a new entry");
// we have no existing contact of this type so create
customer.AddContactInformationToCustomer(c);
}
}
}
updateCustomer.CustomerInternalId = customer.CustomerInternalId;
updateCustomer.CreatedDate = customer.CreatedDate;
updateCustomer.UpdatedDate = Functions.GenerateDateTimeByLocale();
loyalty.Entry(customer).CurrentValues.SetValues(updateCustomer);
loyalty.Entry(customer).State = EntityState.Modified;
if (updateCustomer.BusinessPartnerId == null)
{
Console.WriteLine($"BPID not specified or NULL. Do not update.");
loyalty.Entry(customer).Property(x => x.BusinessPartnerId).IsModified = false;
}
// CustomerPayload used to check name, as Customer has no outer references/element for name details.
if (customerPayload.RequestCustomer.Name == null)
{
loyalty.Entry(customer).Property(x => x.FirstName).IsModified = false;
loyalty.Entry(customer).Property(x => x.LastName).IsModified = false;
loyalty.Entry(customer).Property(x => x.Title).IsModified = false;
}
loyalty.SaveChanges();
customerPayload = customer.Convert(customer);
// Return customer so we can access mcaid, bpid etc.
return customerPayload;
}
}
catch (ArgumentNullException e)
{
Console.WriteLine(e);
throw new CustomerNotFoundException();
}
catch (Exception ex)
{
Console.WriteLine($"{ex}");
throw ex;
}
}
映射标识部分的示例:
public class Identification
{
[DisplayName("business_partner_id")]
[Description("A business_partner_id is required")]
[StringLength(10)]
[DataType(DataType.Text)]
[JsonProperty("business_partner_id", Required = Required.Default)]
public string BusinessPartnerId { get; set; }
[DisplayName("membership_number")]
[Description("A membership_number is required")]
[StringLength(50)]
[DataType(DataType.Text)]
[JsonProperty("membership_number", Required = Required.Default)]
public string MembershipNumber { get; set; }
[DisplayName("loyalty_db_id")]
[Description("A loyalty_db_id is required")]
[StringLength(50)]
[DataType(DataType.Text)]
[JsonProperty("loyalty_db_id", Required = Required.Default)]
public string LoyaltyDbId { get; set; }
}
好的,所以我确信我遗漏了一些东西,因为这是绝对赤裸裸的,但基本的想法如下 如果您的DTO类看起来像这样:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au",
"loyalty_db_id": "4638092"
},
"name": {
"title": "Ms",
"first_name": "tx2bxtqoa",
"surname": "oe6qoto"
},
"date_of_birth": "1980-12-24T00:00:00",
"gender": "F",
"customer_type": "3",
"home_store_id": "777",
"home_store_updated": "1980-12-24T00:00:00",
"store_joined_id": "274",
"store_joined_date": "1980-12-24T00:00:00",
"status_reason": null,
"status": "50",
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": true,
"updating_store": null
}
],
"marketing_preferences": [],
"address": {
"address_line_1": "something stree",
"address_line_2": "Snyder",
"postcode": "3030"
},
"external_cards": [
{
"updating_store": null,
"card_type": "PY",
"card_design": null,
"card_number": "2701138910268",
"status": "ACTIVE",
"physical_print": false
}
]
}
}
public class CustomerPayload
{
public Identification Identification { get; set; }
[JsonProperty("contact_information")]
public ContactInfo[] ContactInformation { get; set; }
}
public class ContactInfo
{
public bool Validated { get; set; }
}
public class Identification
{
[JsonProperty("membership_number")]
public string MembershipNumber { get; set; }
public string SomePropertyNotInPayload { get; set; }
}
public class PartialCustomerPayloadWrapper
{
public JObject Customer { get; set; }
}
我们需要声明一根拐杖(因为某些原因,您的样本具有顶级“客户”属性,如下所示:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au",
"loyalty_db_id": "4638092"
},
"name": {
"title": "Ms",
"first_name": "tx2bxtqoa",
"surname": "oe6qoto"
},
"date_of_birth": "1980-12-24T00:00:00",
"gender": "F",
"customer_type": "3",
"home_store_id": "777",
"home_store_updated": "1980-12-24T00:00:00",
"store_joined_id": "274",
"store_joined_date": "1980-12-24T00:00:00",
"status_reason": null,
"status": "50",
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": true,
"updating_store": null
}
],
"marketing_preferences": [],
"address": {
"address_line_1": "something stree",
"address_line_2": "Snyder",
"postcode": "3030"
},
"external_cards": [
{
"updating_store": null,
"card_type": "PY",
"card_design": null,
"card_number": "2701138910268",
"status": "ACTIVE",
"physical_print": false
}
]
}
}
public class CustomerPayload
{
public Identification Identification { get; set; }
[JsonProperty("contact_information")]
public ContactInfo[] ContactInformation { get; set; }
}
public class ContactInfo
{
public bool Validated { get; set; }
}
public class Identification
{
[JsonProperty("membership_number")]
public string MembershipNumber { get; set; }
public string SomePropertyNotInPayload { get; set; }
}
public class PartialCustomerPayloadWrapper
{
public JObject Customer { get; set; }
}
然后我们可以用一种方法来完成所有的巫术:
private void SetThings(object target, JObject jObj)
{
var properties = target.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(x =>
{
var attr = x
.GetCustomAttributes(typeof(JsonPropertyAttribute), false)
.FirstOrDefault();
string jPropName = null;
if (attr != null)
{
jPropName = ((JsonPropertyAttribute)attr).PropertyName;
}
return (Property: x, Name: x.Name, JsonName: jPropName);
});
foreach (var val in jObj)
{
var key = val.Key.ToLowerInvariant();
var property = properties
.FirstOrDefault(x => x.Name.ToLowerInvariant() == key ||
x.JsonName?.ToLowerInvariant() == key);
if (property == default)
{
continue;
}
if (val.Value.Type == JTokenType.Object)
{
var newTarget = property.Property.GetValue(target);
if (newTarget == null)
{
newTarget = Activator.CreateInstance(property.Property.PropertyType);
property.Property.SetValue(target, newTarget);
}
SetThings(property.Property.GetValue(target), (JObject)val.Value);
}
else
{
property.Property.SetValue(target, val.Value.ToObject(property.Property.PropertyType));
}
}
}
最后,我们的API行动:
[HttpPost]
public string Post([FromBody] PartialCustomerPayloadWrapper wrapper)
{
// So here i expect you to get data from DB
// and then pass through the method that converts the db object to `CustomerPayload`
// Since i do not have that, this is just a POCO with some properties initialized.
var dbCustomer = new CustomerPayload { Identification = new Identification { SomePropertyNotInPayload = "banana" } };
var customer = wrapper.Customer;
SetThings(dbCustomer, customer);
// at this point our SomePropertyNotInPayload is still banana, but contact info and MembershipNumber are set
return "OK";
}
我使用此有效载荷进行测试:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au"
},
"address": {
"address_line_1": "something stree"
},
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": false,
"updating_store": null
}
]
}
}
注意:这种方法最大的缺点是你不能真正地将“联系人信息”结合起来,因为你需要某种主键(我假设它已经在为你的客户准备的过程中)。如果你有,你可以通过检查
JTokenType.Array
来扩展巫毒部分,然后通过类似的设置来处理单个项目。好的,所以我肯定我遗漏了一些东西,因为这完全是赤裸裸的,但基本思想如下
如果您的DTO类看起来像这样:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au",
"loyalty_db_id": "4638092"
},
"name": {
"title": "Ms",
"first_name": "tx2bxtqoa",
"surname": "oe6qoto"
},
"date_of_birth": "1980-12-24T00:00:00",
"gender": "F",
"customer_type": "3",
"home_store_id": "777",
"home_store_updated": "1980-12-24T00:00:00",
"store_joined_id": "274",
"store_joined_date": "1980-12-24T00:00:00",
"status_reason": null,
"status": "50",
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": true,
"updating_store": null
}
],
"marketing_preferences": [],
"address": {
"address_line_1": "something stree",
"address_line_2": "Snyder",
"postcode": "3030"
},
"external_cards": [
{
"updating_store": null,
"card_type": "PY",
"card_design": null,
"card_number": "2701138910268",
"status": "ACTIVE",
"physical_print": false
}
]
}
}
public class CustomerPayload
{
public Identification Identification { get; set; }
[JsonProperty("contact_information")]
public ContactInfo[] ContactInformation { get; set; }
}
public class ContactInfo
{
public bool Validated { get; set; }
}
public class Identification
{
[JsonProperty("membership_number")]
public string MembershipNumber { get; set; }
public string SomePropertyNotInPayload { get; set; }
}
public class PartialCustomerPayloadWrapper
{
public JObject Customer { get; set; }
}
我们需要声明一根拐杖(因为某些原因,您的样本具有顶级“客户”属性,如下所示:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au",
"loyalty_db_id": "4638092"
},
"name": {
"title": "Ms",
"first_name": "tx2bxtqoa",
"surname": "oe6qoto"
},
"date_of_birth": "1980-12-24T00:00:00",
"gender": "F",
"customer_type": "3",
"home_store_id": "777",
"home_store_updated": "1980-12-24T00:00:00",
"store_joined_id": "274",
"store_joined_date": "1980-12-24T00:00:00",
"status_reason": null,
"status": "50",
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": true,
"updating_store": null
}
],
"marketing_preferences": [],
"address": {
"address_line_1": "something stree",
"address_line_2": "Snyder",
"postcode": "3030"
},
"external_cards": [
{
"updating_store": null,
"card_type": "PY",
"card_design": null,
"card_number": "2701138910268",
"status": "ACTIVE",
"physical_print": false
}
]
}
}
public class CustomerPayload
{
public Identification Identification { get; set; }
[JsonProperty("contact_information")]
public ContactInfo[] ContactInformation { get; set; }
}
public class ContactInfo
{
public bool Validated { get; set; }
}
public class Identification
{
[JsonProperty("membership_number")]
public string MembershipNumber { get; set; }
public string SomePropertyNotInPayload { get; set; }
}
public class PartialCustomerPayloadWrapper
{
public JObject Customer { get; set; }
}
然后我们可以用一种方法来完成所有的巫术:
private void SetThings(object target, JObject jObj)
{
var properties = target.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(x =>
{
var attr = x
.GetCustomAttributes(typeof(JsonPropertyAttribute), false)
.FirstOrDefault();
string jPropName = null;
if (attr != null)
{
jPropName = ((JsonPropertyAttribute)attr).PropertyName;
}
return (Property: x, Name: x.Name, JsonName: jPropName);
});
foreach (var val in jObj)
{
var key = val.Key.ToLowerInvariant();
var property = properties
.FirstOrDefault(x => x.Name.ToLowerInvariant() == key ||
x.JsonName?.ToLowerInvariant() == key);
if (property == default)
{
continue;
}
if (val.Value.Type == JTokenType.Object)
{
var newTarget = property.Property.GetValue(target);
if (newTarget == null)
{
newTarget = Activator.CreateInstance(property.Property.PropertyType);
property.Property.SetValue(target, newTarget);
}
SetThings(property.Property.GetValue(target), (JObject)val.Value);
}
else
{
property.Property.SetValue(target, val.Value.ToObject(property.Property.PropertyType));
}
}
}
最后,我们的API行动:
[HttpPost]
public string Post([FromBody] PartialCustomerPayloadWrapper wrapper)
{
// So here i expect you to get data from DB
// and then pass through the method that converts the db object to `CustomerPayload`
// Since i do not have that, this is just a POCO with some properties initialized.
var dbCustomer = new CustomerPayload { Identification = new Identification { SomePropertyNotInPayload = "banana" } };
var customer = wrapper.Customer;
SetThings(dbCustomer, customer);
// at this point our SomePropertyNotInPayload is still banana, but contact info and MembershipNumber are set
return "OK";
}
我使用此有效载荷进行测试:
{
"customer": {
"identification": {
"membership_number": "2701138910268@priceline.com.au"
},
"address": {
"address_line_1": "something stree"
},
"contact_information": [
{
"contact_type": "EMAIL",
"contact_value": "2yupelxqui@hotmails.com",
"validated": true,
"updating_store": null
},
{
"contact_type": "MOBILE",
"contact_value": "xxxxxxxxx",
"validated": false,
"updating_store": null
}
]
}
}
注意:这种方法最大的缺点是你不能真正地将“联系人信息”结合起来,因为你需要某种主键(我假设它已经在为你的客户准备的过程中)。如果你有,你可以通过检查
JTokenType.Array
来扩展巫毒部分,然后通过类似的设置来处理单个项目。我太懒了,无法全部输入,但我要做的是将它们的内容反序列化到
字典中,然后使用反射来提取模型属性,并仅在ictionary键包含它。如果与您一起工作的人对此表示怀疑,那么第二个最好的方法是使用传入模型和db模型,并对其进行反思,但缺点是->如果他们想实际将值设置为null,该怎么办?在字典中,您可以使用.ContainsKey()
但对于您的型号-不是真的。顺便说一句,它在您的有效负载中看起来像一个真实的移动电话号码,可能需要删除它。好的,我将尝试提供一个,可能不是针对您的完整型号。要做到这一点,您能告诉我您是在使用Json.net序列化程序还是新的System.Text.Json
序列化程序吗?您能展示一下您是如何映射的吗<代码>标识。成员身份号到成员身份号
。是自动映射器还是[JsonProperty]
?因为没有这个片段样本就无法工作感谢zaitsman,我已经添加了一些字段的样本以及它们是如何映射的。我本来会添加它的,但上次我问了一些关于这个的问题,并粘贴了一个属性和属性的列表,所以有人对我粘贴了太多的信息进行了抨击。我太懒了键入所有内容,但我要做的是将它们的内容反序列化到一个
字典中,然后使用反射来提取模型属性,并仅在字典键包含它时进行设置。如果你正在与ARK合作的任何人都这样做,那么第二个最好的方法就是使用传入模型和db模型,并对此进行反射,但缺点是->如果他们真的想把一个值设为null呢?如果是字典,你可以使用.ContainsKey()
但对于您的型号-不是真的。顺便说一句,它在您的有效负载中看起来像一个真实的移动电话号码,可能需要删除它。好的,我将尝试提供一个,可能不是针对您的完整型号。要做到这一点,您能告诉我您是在使用Json.net序列化程序还是新的System.Text.Json
序列化程序吗?您能展示一下您是如何映射的吗<代码>标识。成员身份号到成员身份号
。那是automapper?还是[JsonProperty]
?因为没有这个片段样本就不能工作感谢zaitsman,我已经添加了一些字段的样本以及它们的映射方式。我本来会添加它的,但上次我添加了它