谁能向我解释CreatedAtRoute()?


136

在Web API 2的模板中,post方法始终像这样:

[ResponseType(typeof(MyDTO))]
public IHttpActionResult PostmyObject(MyDTO myObject)
{
    ...
    return CreatedAtRoute("DefaultApi", new { id = myObject.Id }, myObject);
}

我不明白这种CreatedAtRoute()方法。谁能CreatedAtRoute()向我解释该方法?


24
@JohnSaunders当然我找到了那些Google结果。我的问题是这些文档没有帮助我理解这种方法,阅读它们后,我还是不明白。这就是为什么我在这里问。
2014年

11
那我不回答你的问题。
2014年

12
如果我可以通过Google查找答案,为什么还要花时间在此处编辑问题并提问呢?
2014年

3
感谢您提出这个问题:)
Vidar

Answers:


157

CreatedAtRoute当您调用POST方法存储一些新对象时,该方法旨在将URI返回到新创建的资源。因此,例如,如果您发布一个订单商品,则可能会返回诸如“ api / order / 11”之类的路由(显然11是订单的ID)。

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


13
它返回的实际上是一个CreatedAtRouteNegotiatedContentResult <myObject>对象!如果您对操作进行单元测试,这就是您所看到的。但是,在http上下文中运行时,它将在正文中返回序列化的对象,但是您应该在响应中看到带有资源链接的标头。顺便说一句,如果您认为我回答了这个问题,您可以标记为答案吗?干杯。

3
谢谢,这回答了我的问题。
武术

2
您提供的路由在响应中显示为“位置”标头。这是相当典型的REST行为
Jeff Martin

4
@seesharper当未返回MyObject时...为什么我必须将其传递给CreatedAtRoute?方法是什么?
伊丽莎白2015年

6
有没有办法使用当前路线?例如,如果我使用[Route("[controller]")]on控制器在文件控制器中创建一个对象,我将返回什么(例如,可以使用URL调用相邻的GET操作)?
Shimmy Weitzhandler '17

17

当您使用CreatedAtRoute时,第一个参数是Get to the resource的方法名称。不太明显的窍门是,即使指定了正确的方法名称,也必须在HttpGet属性上使用Name参数才能使其起作用。

因此,如果您的帖子中的退货是这样的:

return CreatedAtRoute("Get", new { newModel.Id}, newModel);

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

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

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


“这不仅将返回新对象(通常为JSON),还将在响应的URI上设置Location标头,以获取该资源。” 用“ This”表示您是HttpGet还是HttpPost?另外,您的意思是“它将在将获取该资源的URI的响应上设置Location头”。
Tran Anh Minh,

“ This”指的是HttpPost方法(编辑答案)。关于您关于Location标头的问题,这是一个Http标头,客户端可以决定执行某项操作,例如自动重定向到它。这是一个标准的Http响应标头(en.wikipedia.org/wiki/…)。
Scott Blasingame,

请您更新您的答案以包括第二和第三参数的含义。
变量

0

在.net核心WebAPI中,您使用此方法返回201代码,这表示已创建对象。

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

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

routeName 是必须放在方法上的名称,该名称将是创建后将获得该资源的URI。

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

内容 是创建的对象。

上面的示例显示了使用带绑定名称的简单GET方法和创建新对象的POST方法的简单控制器的两种方法的实现。

namespace BastterAPI.Controllers
{
    [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 Company { CompanyID = company.CompanyID }, company);

        }


    }
}

重要

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

  2. 第二个参数上的对象将需要具有用于获取Get方法上的资源所必需的字段,可以说这是自身创建的对象的子集

  3. 最后一个参数是在正文请求中以完整格式收到的公司对象。

最终

最终结果是,当创建新公司的邮政使用此API时,您将返回诸如“ api / company / {id}”之类的路由,该路由将返回给您新创建的资源

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.