c# - api란 web ASP 웹 패치 패치 구현




2 Answers

메소드를 PATCH로 변경해도 웹 API 동작은 변경되지 않습니다. 부분 업데이트를위한 메커니즘은 기본적으로 제공되지 않습니다. 너무 오래 패치 방법이 없었던 이유 중 하나는 패치를 리소스에 적용하기위한 유비쿼터스 미디어 유형이 없다는 것입니다.

둘째, 웹 API에 객체 직렬화를 요청하면 부분적으로 업데이트 된 객체를 적용하는 개념이 없습니다. 동의 할 많은 컨벤션이있을 것입니다. null 값은 무엇을 의미합니까, 빈 값은 무엇이고, 어떻게 "이 DateTime을 업데이트하지 마십시오"라고 말합니까? 관련 객체, 자식 항목은 어떻습니까? 하위 항목을 어떻게 삭제합니까? CLR 팀이 다른 유형의 멤버의 하위 집합 만 포함하는 형식 개념을 구현하지 않는 한 부분 업데이트와 개체 직렬화는 함께 잘 진행되지 않습니다.

Aliostad는 UpdateModel에 대해 언급하고 있으며 이는 media type application/x-www-form-urlencoded 명시 적으로 이름 값 쌍의 임의의 집합을 허용하기 때문에 HTML 양식에서 업데이트 할 때 가능합니다. 진행중인 "객체 직렬화"가 없습니다. Model 객체의 이름과 일치하는 양식의 이름과 일치합니다.

나 자신을 위해, 나는 폼처럼 작동하는 부분적인 업데이트를하는 데 사용하는 새로운 미디어 유형을 만들었지 만 계층 적 데이터를 처리하고 업데이트 순서를 유지한다는 점에서 좀 더 발전했습니다.

web api 2 return 404

이 모델이 있다고 가정하십시오.

public partial class Todo
{
    public int id { get; set; }
    public string content { get; set; }
    public bool done { get; set; }
}

그리고 저는 이것을 json 데이터로 패치 요청으로 컨트롤러에 보냅니다. 이건 분명히 체크 박스를 토글하는 동작입니다. 내 생각에 내가 그걸 내 서버로 보내고 싶다는 생각을하고, 전체 모델이 아니라고 생각한다.

{ "id":1, "done" : true }

이 간단한, json 패치 요청을 올바르게 처리하려면 내 WebApi 컨트롤러가 어떻게 보이게해야합니까? 나는 이것을 위해 웹 API를 사용해야 하는가, 아니면 mvc와 함께 더 많은 rpc 스타일의 접근 방식을 사용해야합니까?

할 일은 아주 기본적인 것 같지만, 제대로 할 수는 없습니다! 내 컨트롤러 메서드에서 다른 매개 변수를 사용해야 할 수도 있지만 확실하지는 않습니다.

시간 내 주셔서 감사합니다.




내 프로젝트에 Microsoft.AspNet.WebApi.OData 를 사용했는데 JSON (제 경우의 숫자로 작업)에 관련된 몇 가지 문제가있었습니다. 또한 OData 패키지에는 내 관점에서 단일 피처 (모든 종속성이있는 ~ 7MB)에 비해 너무 큰 종속성이 있습니다.

그래서 저는 여러분이 요구하는 것을 수행하는 간단한 라이브러리 SimplePatch .

사용하는 방법

다음을 사용하여 패키지를 설치하십시오.

Install-Package SimplePatch

그런 다음 컨트롤러에서 :

[HttpPatch]
public IHttpActionResult PatchOne(Delta<Todo> todo)
{
    if (todo.TryGetPropertyValue(nameof(Todo.id), out int id)) {
        // Entity to update (from your datasource)
        var todoToPatch = Todos.FirstOrDefault(x => x.id == id);
        if (todoToPatch == null) return BadRequest("Todo not found");

        todo.Patch(todoToPatch);     

        // Now todoToPatch is updated with new values            
    } else {
        return BadRequest();
    }     

    return Ok();
}

라이브러리는 대규모 패치도 지원합니다.

[HttpPatch]
public IHttpActionResult PatchMultiple(DeltaCollection<Todo> todos)
{
    foreach (var todo in todos)
    {
        if (todo.TryGetPropertyValue(nameof(Todo.id), out int id))
        {
            // Entity to update (from your datasource)
            var entityToPatch = Todos.FirstOrDefault(x => x.id == Convert.ToInt32(id));
            if (entityToPatch == null) return BadRequest("Todo not found (Id = " + id + ")");

            person.Patch(entityToPatch);
        }
        else
        {
            return BadRequest("Id property not found for a todo");
        }
    }

    return Ok();
}

Entity Framework를 사용하는 경우 Patch 메서드를 호출 한 후 코드 두 줄만 추가하면됩니다.

entity.Patch(entityToPatch);

dbContext.Entry(entityToPatch).State = EntityState.Modified;
dbContext.SaveChanges();

또한 Patch 메서드가 호출 될 때 업데이트 할 일부 속성을 제외 할 수 있습니다. Global.asax 또는 Startup.cs

DeltaConfig.Init((cfg) =>
{
    cfg.ExcludeProperties<Todo>(x => x.id);
});

엔티티로 작업 할 때 모델을 만들고 싶지 않을 때 유용합니다.






Related