2015-08-19 4 views
0

У меня есть приложение ASP.NET, и я пытаюсь использовать ModelState.IsValid, чтобы возвращать сообщения об ошибках, если запрос является ошибочным. Я пытался что-то вроде этого: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 
    } 
] 

ответ

1

Подход, который я использовал в прошлом, чтобы вернуть HttpResponseMessage из метода.

Это позволит вам вернуть тип ошибки (например, https://tools.ietf.org/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.

+0

Работал отлично. Спасибо. Это имеет гораздо больше смысла, чем «IQueryable», который у меня был раньше. –

+0

У меня есть быстрый вопрос о синтаксисе оператора if. Что делать, если я делал оператор if, очень похожий на мой вопрос, но я хотел удалить элемент в базе данных, а не возвращать значение? Как мне изменить его, чтобы вызвать методы удаления, которые не возвращают никаких значений? –

+0

Если вы что-то удалили, вы можете разделить оператор If, а не использовать тернарный оператор (? :) и после удаления вы можете вернуть ответ 204 No Content: return Request.CreateResponse (HttpStatusCode.NoContent); – Fermin

0

Подумайте от ваших потребителей. Как вы собираетесь общаться и документировать это? «Этот вызов 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,