【问题标题】:ModelState.IsValid Returning Incorrect TypeModelState.IsValid 返回不正确的类型
【发布时间】:2015-08-19 18:40:57
【问题描述】:

我有一个 ASP.NET 应用程序,如果查询有缺陷,我正在尝试使用 ModelState.IsValid 返回错误消息。我尝试过这样的事情:

[HttpGet]
[Route("")]
[Route("{id:int}")]
public IQueryable<ToDoTable> Get(int id = -1)
{
    if (!ModelState.IsValid)
    {
        var errorList = (from item in ModelState
                         where item.Value.Errors.Any()
                         select item.Value.Errors[0].ErrorMessage).ToList();
        return errorList.AsQueryable();
    }
    else
    {
        if (id == -1)
            return db.ToDoTables;
        else
            return db.ToDoTables.Where(lt => lt.ID == id);
    }
}

但是,问题在于errorList 的类型为string,并且该函数期望返回类型为ToDoTable,这是我创建的一个类。如何获得正确的返回类型?还是我需要改变函数的期望?我是否必须将方法添加到类中(甚至不确定是否可行)?

当ModelState.IsValid 为真时,该函数将返回类对象以及从我正在查询的数据库中收集的信息,并将其输出为JSON。示例:

[
  {
    "ID": 11,
    "Title": "this is a test",
    "Description": "this is specifically to test the put method",
    "Due": null,
    "Completed": true
  },
  {
    "ID": 15,
    "Title": "date test",
    "Description": "datetime format",
    "Due": "2015-08-10T02:41:29",
    "Completed": true
  }
]

【问题讨论】:

    标签: asp.net asp.net-web-api modelstate


    【解决方案1】:

    我过去使用的一种方法是从方法中返回一个HttpResponseMessage。

    这将允许您返回“错误”类型(例如 https://datatracker.ietf.org/doc/html/draft-nottingham-http-problem)和适当的响应代码(例如 400)。

    然后你的函数变成:

    [HttpGet]
    [Route("")]
    [Route("{id:int}")]
    public HttpResponseMessage Get(int id = -1)
    {
        if (!ModelState.IsValid)
        {
            var errorList = (from item in ModelState
                             where item.Value.Errors.Any()
                             select item.Value.Errors[0].ErrorMessage).ToList();
            return Request.CreateResponse(HttpStatusCode.BadRequest, errorList);
        }
        else
        {
    
            var tables = (id == -1) ? db.ToDoTables : db.ToDoTables.Where(lt => lt.ID == id);
            return Request.CreateResponse(HttpStatusCode.OK, tables);
        }
    }
    

    这意味着您可以在不抛出 HttpResponseExceptions 的情况下应对不同的响应类型和状态。

    【讨论】:

    • 完美运行。谢谢你。这比我之前的IQueryable 更有意义。
    • 我有一个关于 if 语句语法的快速问题。如果我正在做一个与我的问题非常相似的 if 语句,但我想删除数据库中的一个项目而不是返回一个值怎么办?我将如何修改它以调用不返回任何值的删除方法?
    • 如果您删除了某些内容,您可以拆分 If 语句而不是使用三元运算符 (?:),删除后您可以返回 204“无内容”响应:return Request.CreateResponse(HttpStatusCode.无内容);
    【解决方案2】:

    从消费者的角度思考。你将如何沟通和记录这一点? “此 API 调用返回 Foo,但返回 Bar 的情况除外”。

    这是可能的,但是您需要将返回类型更改为IHttpActionResult 或throw new HttpResponseException。

    (可以说)更好的是引入具有可为空属性的响应容器,如下所示:

    public class ApiResponse<T>
    {
        public bool Success { get; set; }
    
        public int? RecordCount { get; set; }
    
        public T Content { get; set; }
    
        public ErrorDetail Error { get; set; }
    }
    

    这样,您的所有操作都可以从静态类型化(想想单元测试)中受益,并以相同的方式返回成功和失败。

    相关:Handle ModelState Validation in ASP.NET Web API、Best practice to return errors in ASP.NET Web API、Storing result of Web API call into Generic type class、

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2021-06-16
      • 2014-12-12
      • 1970-01-01
      • 2015-06-18
      相关资源
      最近更新 更多