为什么我的属性路由不起作用?

时间:2017-10-29 06:55:04

标签: asp.net-mvc asp.net-core-mvc dotnet-httpclient attributerouting

这就是我的控制器的样子:

[Route("api/[controller]")]
[Produces("application/json")]
public class ClientsController : Controller
{
    private readonly IDataService _clients;

    public ClientsController(IDataService dataService)
    {
        _clients = dataService;
    }

    [HttpPost]
    public int Post([Bind("GivenName,FamilyName,GenderId,DateOfBirth,Id")] Client model)
    {
        // NB Implement.
        return 0;
    }

    [HttpGet("api/Client/Get")]
    [Produces(typeof(IEnumerable<Client>))]
    public async Task<IActionResult> Get()
    {
        var clients = await _clients.ReadAsync();
        return Ok(clients);
    }

    [HttpGet("api/Client/Get/{id:int}")]
    [Produces(typeof(Client))]
    public async Task<IActionResult> Get(int id)
    {
        var client = await _clients.ReadAsync(id);
        if (client == null)
        {
            return NotFound();
        }

        return Ok(client);
    }

    [HttpGet("api/Client/Put")]
    public void Put(int id, [FromBody]string value)
    {
    }

    [HttpGet("api/Client/Delete/{id:int}")]
    public void Delete(int id)
    {
    }
}

然而,当我请求网址/api/Clients/Get时,如下所示:

json = await Client.GetStringAsync("api/Clients/Get");

我回到了以下异常:

  

AmbiguousActionException:匹配多个动作。下列   动作匹配路线数据并满足所有约束条件:

     

Assessment.Web.Controllers.ClientsController.Index(Assessment.Web)   Assessment.Web.Controllers.ClientsController.Details(Assessment.Web)   Assessment.Web.Controllers.ClientsController.Create(Assessment.Web)

ClientHttpClient。请注意,尽管名称相同id,但没有GET操作与路径数据匹配。

这里可能有什么问题?

2 个答案:

答案 0 :(得分:4)

您使用的属性错误。

您在控制器上有路线

[Route("api/[controller]")]

将映射到api/Clients并将其作为控制器中任何操作路由的前缀。

这意味着

[HttpGet("api/Client/Get")] // Matches GET api/Clients/api/Client/Get
[Produces(typeof(IEnumerable<Client>))]
public async Task<IActionResult> Get()
{
    var clients = await _clients.ReadAsync();
    return Ok(clients);
}

由于控制器上的路由前缀,将GET与api/Clients/api/Client/Get匹配。

引用Routing to Controller Actions

您需要相应地更新操作的属性路径

[Route("api/[controller]")]
[Produces("application/json")]
public class ClientsController : Controller {
    private readonly IDataService _clients;

    public ClientsController(IDataService dataService)
    {
        _clients = dataService;
    }

    [HttpPost] //Matches POST api/Clients
    public int Post([Bind("GivenName,FamilyName,GenderId,DateOfBirth,Id")] Client model) {
        // NB Implement.
        return 0;
    }

    [HttpGet("Get")] //Matches GET api/Clients/Get
    [Produces(typeof(IEnumerable<Client>))]
    public async Task<IActionResult> Get() {
        //...code removed for brevity
    }

    [HttpGet("Get/{id:int}")] //Matches GET api/Clients/Get/5
    [Produces(typeof(Client))]
    public async Task<IActionResult> Get(int id) {
        //...code removed for brevity
    }

    [HttpGet("Put")] //Matches PUT api/Clients/Put
    public void Put(int id, [FromBody]string value) {
        //...code removed for brevity
    }

    [HttpGet("Delete/{id:int}")] //Matches GET api/Clients/Delete/5
    public void Delete(int id) {
    }
}

删除操作实际上应该重构为HTTP DELETE,并且应该返回IActionResult

[HttpDelete("Delete/{id:int}")] //Matches DELETE api/Clients/Delete/5
public IActionResult Delete(int id) {
    //...code removed for brevity
}

答案 1 :(得分:0)

我认为路线中有拼写错误,应该是客户 s ,最后是(s)而非客户。

[HttpGet("api/Clients/Get")]

而不是

[HttpGet("api/Client/Get")]

或者将对端点的调用更改为:

 json = await Client.GetStringAsync("api/Client/Get");