如何使用命令(API)和查询(odata)控制器将位置标头传递给响应

Posted

技术标签:

【中文标题】如何使用命令(API)和查询(odata)控制器将位置标头传递给响应【英文标题】:How to pass Location header to response with command(API) and query(odata) controllers 【发布时间】:2020-03-03 06:46:38 【问题描述】:

场景

您好,我有用 ASP.Net core 2.2 编写的命令 API 控制器。控制器继承自 ControllerBase 并具有属性 ApiController。我想添加 Location 标头。我也查询了 odata 控制器。 Odata 版本:7.2.2

Odata 代码:

我的 Odata 控制器:

[ODataRoutePrefix("categories")]
public class ODataCategoriesController : ODataController

Odata 获取操作:

[EnableQuery]
[ODataRoute("id")]
public async Task<ActionResult<Category>> GetAsync(Guid id)

启动

opt.EnableEndpointRouting = false;
...
app.UseHttpsRedirection();
app.UseMvc(options =>

     options.EnableDependencyInjection();
     options.Select().Filter().OrderBy().Count().Expand().MaxTop(100).SkipToken();
     options.MapODataServiceRoute("odata", "api/odata", GetExplicitEdmModel());
);

试过

我尝试过使用 CreatedAtAction,但收到:InvalidOperationException: No route 与提供的值匹配。

在我的 POST 控制器中:

return CreatedAtAction("Get", "ODataCategories", new  id= categoryResponse.Id , categoryResponse);

试过 2

我也尝试过手动返回 Location 标头。但我收到: 响应中不存在标题。

代码

    [HttpPost]
    [ProducesResponseType((int)HttpStatusCode.Created)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    public async Task<ActionResult<CreateCategoryResponse>> PostCategory(
        [FromBody]CreateCategoryCommand createCategoryCommand)
    
        CreateCategoryResponse categoryResponse =
            await _mediator.Send(createCategoryCommand);

        if (categoryResponse == null)
        
            return BadRequest();
        

        HttpContext.Response.Headers["Location"] = 
            $"SomeBuiltLocation";
        return Created("", categoryResponse);
    

总结

我正在寻找使我能够包含 Location 标头的解决方案。无论是使用 CreatedAt 还是手动操作都没有关系。

【问题讨论】:

【参考方案1】:

应该也可以手工制作。

[HttpPost]
[ProducesResponseType((int)HttpStatusCode.Created)]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
public async Task<ActionResult<CreateCategoryResponse>> PostCategory(
    [FromBody]CreateCategoryCommand createCategoryCommand) 
    CreateCategoryResponse categoryResponse =
        await _mediator.Send(createCategoryCommand);

    if (categoryResponse == null) 
        return BadRequest();
    

    var result = new CreatedResult("SomeBuiltLocation", categoryResponse);
    return result;

【讨论】:

你知道是否可以通过引用odata控制器动作来创建Location头吗?

以上是关于如何使用命令(API)和查询(odata)控制器将位置标头传递给响应的主要内容,如果未能解决你的问题,请参考以下文章

使用 $expand 时的 Web API OData 媒体类型格式化程序

如何允许将 Odata 选项应用于 cosmos db 集合并返回过滤后的记录

如何获取 OData 可查询 Web API 端点过滤器并从 DTO 对象映射它?

ODATA WEB API----ODATA服务与客户端

在没有实体框架的情况下创建 Odata Web API 应用程序

如何使用 C# 为 OData 查询中指定的每个过滤器获取一组键/值对?