今天解决了web api中 patch方法的功能,patch方法是什么请自行百度

因为都没有提供原生的解决方案,所以每个人解决的思路各不相同。

我解决的思路是,前台不修改原有数据结构,只需要传入需要修改的值,其它不可以不传。

然后后台先用id查询出整体的实体,然后通过反射遍历前台传入的实体,数据不为null的就取出来,赋值到后台的实体上,最后同put方法一样修改整体实体。

虽然这个方法看上去有点low,但是思路很清楚,不会很乱。方法如下:

前台传入的json

 1    {
 2         "PatientId": "9047df37-d43d-485a-8eda-1cd0b8228655",
 3         "Details": {
 4             "FirstName": "a2222222",
 5             "LastName": "c"
 6         },
 7         "Anatomy": {
 8             "BodyWeight": 22222
 9         },
10         "PersonalInfo": {
11            
12             "EmailAddressPrimary": "cxd@a.com"
13         }
14     }

 后台patch方法

 1         [Route("api/patients/{id}")]
 2         [HttpPatch]
 3         public async Task<IHttpActionResult> Patch(Guid id, Patient patient)
 4         {
 5             try
 6             {
 7                 //后台先用id查询出整体的实体
 8                 Patient indb_Patient = await PatientRepository.GetInstance().GetPatient(id);
 9                 //然后通过反射遍历前台传入的实体,数据不为null的就取出来,赋值到后台的实体上,最后同put方法一样修改整体实体
10                 //这有一个小问题,如果前台想给这个值赋值为null就没办法实现了,因为数值为null会跳过
11                 PatchConvertEntity.PatchConvertToEntity(patient, indb_Patient);
12                 //因为怕前台不传ID所以赋值一下
13                 indb_Patient.PatientId = id;
14                 await PatientRepository.GetInstance().EditPatient(id, indb_Patient);
15                 return StatusCode(HttpStatusCode.NoContent);
16             }
17             catch (Exception ex)
18             {
19                 return BadRequest(ex.Message);
20             }
21         }

反射遍历实体类的方法:

 1     public class PatchConvertEntity
 2     {
 3         public static void PatchConvertToEntity<T>(T sendT, T indb_T)
 4         {
 5             PropertyInfo[] send_propertyInfos = sendT.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
 6             PropertyInfo[] indb_propertyInfos = indb_T.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
 7 
 8             for (int i = 0; i < send_propertyInfos.Length; i++)
 9             {
10                 string sendName = send_propertyInfos[i].Name;
11                 object sendValue = send_propertyInfos[i].GetValue(sendT, null);
12                 // if send data is null ,it will next data
13                 if (sendValue == null)
14                 {
15                     continue;
16                 }
17 
18                 if (send_propertyInfos[i].PropertyType.IsValueType || send_propertyInfos[i].PropertyType.Name.StartsWith("String"))
19                 {
20                     indb_propertyInfos[i].SetValue(indb_T, sendValue);
21                 }
22                 else
23                 {
24                     object indbValue = indb_propertyInfos[i].GetValue(indb_T, null);
25                     PatchConvertToEntity(sendValue, indbValue);
26                 }
27             }
28         }
29     }

修改方法就不多写了,就是一个普通的修改方法

db.Entry(patient).State = EntityState.Modified;
db.SaveChanges();

实体类设计要注意一下:

Guid \ enum \ datetime 等类型,要设计可空,如果不可空,前台不传时会有默认值。 

        public Guid? PatientKeyId { get; set; }
        public Gender? Gender { get; set; }
        public DateTime? CreateTime { get; set; }

 

 

【这个功能自己测试了一下没有问题,还需要其它类的测试】

 

posted on 2017-11-15 09:15  cxd1008  阅读(390)  评论(0编辑  收藏  举报