【问题标题】:Passing two parameters as composite primary key to HttpGet Attribute将两个参数作为复合主键传递给 HttpGet 属性
【发布时间】:2018-01-29 09:07:41
【问题描述】:

我有两个问题。我正在做 .NET 核心 Web REST API。 (核心 2.0)。我有一个链接表,其主键由两列(复合主键)组成。如何将两个(两列)参数都传递给 [HttpGet] 属性,以便通过其数据库 id 获取数据?我使用了/ 像这篇文章建议的字符:MVC6 attribute routing with two parameters 但它对我不起作用。我总是在没有任何参数而不是 GetUserPermissionByID() 的情况下调用更通用的 [HttpGet] 操作。 GetUserPermissionByID() 永远不会被调用。

第二个问题与第一个问题有关。在[HttpPost] 操作中在同一控制器中创建对象时,我使用CreatedAtRoute() 方法将新创建的对象传递给客户端。但是如何正确编写它以将复合主键作为 ID 发送回来?

我的代码:

型号

public class UserPermission
{
    public int IDUser { get; set; }
    public int IDPermission { get; set; }
    public User User { get; set; }
    public Permission Permission { get; set; }
}

控制器 - 按 ID 获取

[HttpGet("{idUser}/{idPermission}", Name = "GetUserPermissionByID")]
public async Task<IActionResult> GetUserPermissionByID(int idUser, int idPermission)
{
    try
    {
        var userPermission = _context.UsersPermissions.Where(up => up.IDUser == idUser && up.IDPermission == idPermission).FirstOrDefaultAsync();

        if (userPermission == null)
        {
            return NotFound();
        }
        else
        {
            return new ObjectResult(userPermission);
        }
    }
    catch (System.Exception ex)
    {
        Helpers.ExceptionLogger.LogException(ex);
        return StatusCode(500);
    }
}

控制器 - 发布

[HttpPost]
public async Task<IActionResult> CreateUnitPermission([FromBody] UserPermission userPermissionToCreate)
{
    if (userPermissionToCreate == null)
    {
        return BadRequest();
    }
    else
    {
        try
        {
            _context.UsersPermissions.Add(userPermissionToCreate);

            await _context.SaveChangesAsync();

            return CreatedAtRoute("GetUserPermissionByID", new { id = new { userPermissionToCreate.IDUser, userPermissionToCreate.IDPermission } }, userPermissionToCreate); // it doesn't work 
        }
        catch (Exception ex)
        {
            Helpers.ExceptionLogger.LogException(ex);
            return StatusCode(500);
        }
    }
}

【问题讨论】:

  • I always get my more general [HttpGet] action - 请同时显示该操作的路由。 + 添加您请求的 URL 示例。另外,你指定默认路由了吗?
  • 您的问题与复合键无关。这是一个简单的路由问题。路由框架总是短路路由。换句话说,它会找到满足给定 URL/参数的第一条路由,无论这是否是您真正想要的路由。您可以使用命名路由和/或显式路由顺序来解决很多此类问题,但鉴于我们无法了解其他路由可能与该路由冲突,因此我们无能为力。

标签: c# asp.net-core asp.net-mvc-routing asp.net-core-webapi


【解决方案1】:

例如,如果控制器看起来像这样

[Route("api/[controller]")]
public class PermissionController : Controller {

    //Matches GET api/permission/1234/98766
    [HttpGet("{idUser}/{idPermission}", Name = "GetUserPermissionByID")]
    public async Task<IActionResult> GetUserPermissionByID(int idUser, int idPermission) {
        //...code removed for brevity
    }

}

GetUserPermissionByID 将映射到类似于api/permission/{user id here}/{permission id here} 的 URL

为确保参数与路由模板正确匹配,您还可以使用路由约束来避免冲突

[HttpGet("{idUser:int}/{idPermission:int}", Name = "GetUserPermissionByID")]

参考Route Constraint Reference

在告诉框架在哪里查找和绑定模型时,Core 也更加严格,因此请考虑使用绑定属性

//Matches GET api/permission/1234/98766
[HttpGet("{idUser:int}/{idPermission:int}", Name = "GetUserPermissionByID")]
public async Task<IActionResult> GetUserPermissionByID([FromQuery]int idUser, [FromQuery]int idPermission) {
    //...code removed for brevity
}

参考Customize model binding behavior with attributes

对于第二个问题,参数没有正确传递。匿名对象的属性必须匹配目标操作的参数才能映射操作。

return CreatedAtRoute(
    "GetUserPermissionByID", 
    new { 
        idUser = userPermissionToCreate.IDUser, 
        idPermission = userPermissionToCreate.IDPermission 
    }, 
    userPermissionToCreate
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    • 2014-08-27
    • 1970-01-01
    相关资源
    最近更新 更多