谁能向我解释 CreatedAtRoute() 吗?

Posted

技术标签:

【中文标题】谁能向我解释 CreatedAtRoute() 吗?【英文标题】:Can anyone explain CreatedAtRoute() to me? 【发布时间】:2014-09-22 14:43:08 【问题描述】:

从 Web API 2 的模板来看,post 方法总是这样:

[ResponseType(typeof(MyDTO))]
public IHttpActionResult PostmyObject(MyDTO myObject)

    ...
    return CreatedAtRoute("DefaultApi", new  id = myObject.Id , myObject);

我不明白这个CreatedAtRoute() 方法。谁能给我解释一下?

【问题讨论】:

@JohnSaunders 当然我找到了那些谷歌结果。我的问题是这些文档并不能帮助我理解这个方法,读了之后我还是不明白。这就是我在这里问的原因。 如果我可以谷歌并找到答案,我为什么还要花时间在这里编辑问题并提出问题? 感谢您提出这个问题 :) 【参考方案1】:

CreatedAtRoute 方法旨在在您调用 POST 方法来存储一些新对象时返回指向新创建资源的 URI。 因此,例如,如果您发布一个订单商品,您可能会返回一个类似 'api/order/11' 的路由(11 显然是订单的 id)。

顺便说一句,我同意 MSDN 文章对理解这一点毫无用处。您实际返回的路线自然取决于您的路线设置。

【讨论】:

它返回的实际上是一个 CreatedAtRouteNegotiatedContentResult 对象!如果您对您的操作进行单元测试,这就是您将看到的。但是,当在 http 的上下文中运行时,它会在正文中返回序列化的对象,但是您应该在响应中看到带有资源链接的标头。顺便说一句,如果你认为我回答了这个问题,你能标记为答案吗?干杯。 谢谢,这回答了我的问题。 您提供的路由在响应中显示为 Location 标头。这是相当典型的 REST 行为 @seesharper 当 MyObject 没有返回但......为什么我必须将它传递给 CreatedAtRoute?这个方法是做什么用的? 有没有办法使用当前路线?例如,如果我在文件控制器中使用控制器上的[Route("[controller]")] 创建一个对象,我会返回什么(例如,可以使用 URL 调用相邻的 GET 操作)?【参考方案2】:

当您使用CreatedAtRoute 时,第一个参数是GET 到资源的路由 名称。不那么明显的技巧是,即使指定了正确的方法名称,您也必须使用 HttpGet 属性上的 Name 参数才能使其工作。

因此,如果您的POST 中的返回是这样的:

return CreatedAtRoute("Get", routeValues: new  id = model.Id , value: model);

那么即使您的方法名为 Get,您的 Get 方法属性也应如下所示:

[HttpGet("id", Name = "Get")]

对 Post 方法的调用不仅会返回新对象(通常为 JSON),还会在对获取该资源的 URI 的响应中设置 Location 标头。

注意routeValues字段名称中的字段名称需要匹配目标路由中的绑定名称,即需要有一个名为id的字段匹配HttpGet("id"中的id

最后,在某些情况下,应该提到the CreatedAtAction helper 可以是更直接的解决方案。

【讨论】:

“这不仅会返回新对象(通常为 JSON),还会在对获取该资源的 URI 的响应中设置 Location 标头。” “这个”是指 HttpGet 还是 HttpPost?另外,“它将在对获取该资源的 URI 的响应上设置 Location 标头”是什么意思? "This" 指的是 HttpPost 方法(编辑答案)。至于您关于 Location 标头的问题,这是一个 Http 标头,客户端可以决定使用它自动重定向到它。这是一个标准的 Http 响应标头 (en.wikipedia.org/wiki/…)。【参考方案3】:

在.net core WebAPI中,使用该方法返回201代码,表示对象已创建。

[Microsoft.AspNetCore.Mvc.NonAction]
public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute (string routeName, object routeValues, object content);

如上所示,CreatedAtRoute 可以接收 3 个参数:

路线名称 是您必须放在方法上的名称,该方法将成为创建后获取该资源的 URI。

路由值 它是包含将在命名路由处传递给 GET 方法的值的对象。它将用于返回创建的对象

内容 它是创建的对象。

上面的例子展示了一个简单控制器的两个方法的实现,一个是简单的 GET 方法,一个是绑定名称,另一个是创建一个新对象的 POST 方法。

[Route("api/[controller]")]
[ApiController]
public class CompanyController : Controller

    private ICompanyRepository _companyRepository;

    public CompanyController(ICompanyRepository companyRepository)
    
        _companyRepository = companyRepository;
    

    [HttpGet("id", Name="GetCompany")]
    public IActionResult GetById(int id)
    
        Company company = _companyRepository.Find(id);

        if (company == null)
        
            return NotFound();
        
        
        return new ObjectResult(company);
    

    [HttpPost]
    public IActionResult Create([FromBody] Company company)
    
        if (company == null)
        
            return BadRequest();
        

        _companyRepository.Add(company);

        return CreatedAtRoute(
            "GetCompany",
            new  id = company.CompanyID ,
            company);
    


重要

    注意CreatedAtRoute(routeName)处的第一个参数,必须与Get方法处Name的定义相同。

    第二个参数上的对象将需要具有用于在 Get 方法上检索资源的必要字段,您可以说它是自己创建的对象的子集

    最后一个参数是完整形式的正文请求中收到的公司对象。

终于

作为最终结果,当创建新公司的 Post 使用此 API 时,您将返回一个类似 'api/company/id' 的路由,该路由将返回给您新创建的资源

【讨论】:

这个答案被低估了。我其实明白这里的意思。

以上是关于谁能向我解释 CreatedAtRoute() 吗?的主要内容,如果未能解决你的问题,请参考以下文章

谁能向我解释这段代码?

谁能向我解释以下代码中的 java continue 语句执行?

谁能向我解释为什么b_list不打印c_list?

JQuery 命名空间是一个好习惯吗?

为啥项目数据这么大?

.NET Timer 控件在窗口最小化时运行得更快