将对象引用传递到.NET Core Web API的正确方法

时间:2018-08-06 01:08:30

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

我只是从.NET Web API编程开始,我对经验丰富的.NET开发人员有一个疑问-将对象引用传递到Create端点的“正确”方法是什么?

我有以下型号:

public class Task
{
    public int ID { get; set; }
    public string Title { get; set; }
    public virtual User User { get; set; }
}

public class User
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

还有我的控制器-端点来创建Task

[HttpPost]
public async Task<IActionResult> PostTask([FromBody] Models.Task task)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    _context.Task.Add(task);
    await _context.SaveChangesAsync();

    return CreatedAtAction("GetTask", new { id = task.ID }, task);
}

默认情况下,这有一些有趣的行为。它期望将整个User模型传递到POST请求中(见下文),并在传递时实际创建用户:

{
  "id": 0,
  "title": "string",
  "user": {
    "id": 0,
    "firstName": "string",
    "lastName": "string"
  }
}

我从技术上理解了为什么会这样做,但这绝对不是真正的应用程序中的行为-所以我的问题是-通过UserID并进行验证的“正确/适当”方式是什么? .NET中的模型?我是否应该放弃使用“ ModelState.IsValid”并进行手动验证?

作为第二个问题-我正在使用NSwag从我的API生成Swagger文档,并且它显示“ id”作为需要传递到POST方法中的参数。显然,ID无法通过代码生成而被传递,但是有没有办法让Swagger不将ID显示为可传递的属性?

2 个答案:

答案 0 :(得分:1)

然后创建一个数据传输模型,该模型仅公开要通过网络发送的数据。

public class NewTaskDto {
    [Required]
    public string Title { get; set; }
    [Required]
    public int UserId { get; set; }
}

并将数据以及需要进行验证的数据映射到服务器上的模型。例如,检查UserId是否存在并有效。​​

[HttpPost]
public async Task<IActionResult> PostTask([FromBody] NewTaskDto data) {

    if(data != null) {
        validateUserId(data.UserId, ModelState);
    }

    if (!ModelState.IsValid) {
        return BadRequest(ModelState);
    }

    Models.Task task = MapDataToTask(data); //create Task and copy members

    await saveTask(task);

    return CreatedAtAction("GetTask", new { id = task.ID }, task);
}

这样,该文档将只能看到,并针对所暴露的成员进行报告。

答案 1 :(得分:0)

属性[Required]是必需的,然后您可以检查参数。