将两个参数作为复合主键传递给HttpGet属性

时间:2018-01-29 09:07:42

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

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

第二个问题与第一个问题有关。在CreatedAtRoute()操作中在同一控制器中创建对象时,我使用public class UserPermission { public int IDUser { get; set; } public int IDPermission { get; set; } public User User { get; set; } public Permission Permission { get; set; } } 方法将新创建的对象传递给客户端。但是如何正确地写它以复合主键作为ID发回?

我的代码:

MODEL

[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);
    }
}

CONTROLLER - 按ID获取

[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);
        }
    }
}

CONTROLLER - POST

SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm

1 个答案:

答案 0 :(得分:0)

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

[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}

的网址

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

[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
);