簡體   English   中英

如何使用 IHttpActionResult 對 Created-201 響應進行編碼

[英]How can I code a Created-201 response using IHttpActionResult

如何使用IHttpActionResult對 Created-201 響應進行編碼?

IHttpActionResult只有這些選項

  • 項目清單
  • 未找到
  • 例外
  • 未經授權
  • 錯誤的請求
  • 沖突重定向
  • 無效模型狀態

我現在正在做的是下面的這段代碼,但我想使用IHttpActionResult而不是HttpResponseMessage

public IHttpActionResult Post(TaskBase model)
{
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, model);
    response.Headers.Add("Id", model.Id.ToString());
    return ResponseMessage(response);
}

如果您的視圖派生自ApiController ,您應該能夠從基類調用Created方法來創建這樣的響應。

樣本:

[Route("")]
public async Task<IHttpActionResult> PostView(Guid taskId, [FromBody]View view)
{
    // ... Code here to save the view

    return Created(new Uri(Url.Link(ViewRouteName, new { taskId = taskId, id = view.Id })), view);
}
return Content(HttpStatusCode.Created, "Message");

內容正在返回 NegotiatedContentResult。 NegotiatedContentResult 實現了 IHttpActionResult。

在此處輸入圖片說明

在此處輸入圖片說明

一個類似的問題:如果你想用消息發送 NotFound。

return Content(HttpStatusCode.NotFound, "Message");

或者:

return Content(HttpStatusCode.Created, Class object);
return Content(HttpStatusCode.NotFound, Class object);

在 ASP.NET Core 中,可以返回IActionResult 這意味着您可以返回帶有 201 狀態代碼的ObjectResult

[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] CreateModel createModel)
{
    // Create domain entity and persist
    var entity = await _service.Create(createModel);

    // Return 201
    return new ObjectResult(entity) { StatusCode = StatusCodes.Status201Created };
}

或者,根據 Chris 的建議,您可以使用或“ StatusCode ”方法返回一個 IActionResult,方法如下:

[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] CreateModel createModel)
{
    // Create domain entity and persist
    var entity = await _service.Create(createModel);

    // Return 201
    return StatusCode(StatusCodes.Status201Created, entity);
}

我知道這是一個舊線程,但您可能想在這里查看我的解決方案。 它比需要的多一點,但肯定會完成這項工作。

腳步:

定義自定義屬性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class UniqueIdAttribute: Attribute
    {
    }

使用自定義屬性裝飾模型的唯一標識屬性:

   public class Model
    {
        public List<Model> ChildModels { get; set; }
        [UniqueId]
        public Guid ModelId { set; get; }
        public Guid ? ParentId { set; get; }
        public List<SomeOtherObject> OtherObjects { set; get; }
    }

添加一個新的Created(T yourobject); 方法到從 ApiController 繼承的 BaseController。 從這個 BaseController 繼承你的所有控制器:

CreatedNegotiatedContentResult<T> Created<T>(T content)
    {
        var props =typeof(T).GetProperties()
        .Where(prop => Attribute.IsDefined(prop, typeof(UniqueIdAttribute)));
        if (props.Count() == 0)
        {
            //log this, the UniqueId attribute is not defined for this model
            return base.Created(Request.RequestUri.ToString(), content);
        }
        var id = props.FirstOrDefault().GetValue(content).ToString();
        return base.Created(new Uri(Request.RequestUri + id), content);
     }

它非常簡單,而不必擔心在每種方法中都寫這么多。 你所要做的就是調用Created(yourobject);

如果您忘記裝飾或無法裝飾模型(出於某種原因), Created() 方法仍然有效。 但是,位置標頭會錯過 Id。

您對該控制器的單元測試應該解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM