我希望这可以帮助你使用Microsoft JsonPatchDocument:
.Net Core 2.1控制器中的补丁操作:
[HttpPatch("{id}")]
public IActionResult Patch(int id, [FromBody]JsonPatchDocument<Node> value)
{
try
{
//nodes collection is an in memory list of nodes for this example
var result = nodes.FirstOrDefault(n => n.Id == id);
if (result == null)
{
return BadRequest();
}
value.ApplyTo(result, ModelState);//result gets the values from the patch request
return NoContent();
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex);
}
}
Node模型类:
[DataContract(Name ="Node")]
public class Node
{
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "node_id")]
public int Node_id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "full_name")]
public string Full_name { get; set; }
}
更新“full_name”和“node_id”属性的有效Patch JSon将是操作数组,例如:
[
{ "op": "replace", "path": "full_name", "value": "NewNameWithPatch"},
{ "op": "replace", "path": "node_id", "value": 10}
]
如您所见,“op”表示您想执行的操作,最常见的是“replace”,它将只为新值设置该属性的现有值,但还有其他选项:
[
{ "op": "test", "path": "property_name", "value": "value" },
{ "op": "remove", "path": "property_name" },
{ "op": "add", "path": "property_name", "value": [ "value1", "value2" ] },
{ "op": "replace", "path": "property_name", "value": 12 },
{ "op": "move", "from": "property_name", "path": "other_property_name" },
{ "op": "copy", "from": "property_name", "path": "other_property_name" }
]
这里是我基于反射所构建的扩展方法,用于实现C#中Patch("replace")规范。您可以使用它将任何对象序列化以执行Patch (“replace”)操作。同时,您还可以传递所需的编码方式,它将返回一个HttpContent (StringContent),可直接发送给httpClient.PatchAsync(endPoint, httpContent):
public static StringContent ToPatchJsonContent(this object node, Encoding enc = null)
{
List<PatchObject> patchObjectsCollection = new List<PatchObject>();
foreach (var prop in node.GetType().GetProperties())
{
var patch = new PatchObject{ Op = "replace", Path = prop.Name , Value = prop.GetValue(node) };
patchObjectsCollection.Add(patch);
}
MemoryStream payloadStream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(patchObjectsCollection.GetType());
serializer.WriteObject(payloadStream, patchObjectsCollection);
Encoding encoding = enc ?? Encoding.UTF8;
var content = new StringContent(Encoding.UTF8.GetString(payloadStream.ToArray()), encoding, "application/json");
return content;
}
}
注意到tt也使用我创建的这个类来使用DataContractJsonSerializer序列化PatchObject:
[DataContract(Name = "PatchObject")]
class PatchObject
{
[DataMember(Name = "op")]
public string Op { get; set; }
[DataMember(Name = "path")]
public string Path { get; set; }
[DataMember(Name = "value")]
public object Value { get; set; }
}
使用C#编写的如何使用扩展方法和HttpClient发出Patch请求的示例:
var nodeToPatch = new { Name = "TestPatch", Private = true };//You can use anonymous type
HttpContent content = nodeToPatch.ToPatchJsonContent();//Invoke the extension method to serialize the object
HttpClient httpClient = new HttpClient();
string endPoint = "https://localhost:44320/api/nodes/1";
var response = httpClient.PatchAsync(endPoint, content).Result;
谢谢
JsonPatchDocument
,而您的客户希望发送一个直接的 API 调用,并仅指定一些属性,就像您在示例中所做的那样 - 请查看patcharp
库 https://github.com/mexanichp/patcharp这可以为您提供方向,或者一旦发布,您可以将其作为 NuGet 包使用。 - mexanichp