2015-02-20 1 views
2

В проекте ASP.NET Web API у меня есть фильтр действий, который проверяет ошибки состояния модели и возвращает код состояния Bad Request, если они есть. Это выглядит следующим образом:IActionFilter возвращает новую задачу <HttpResponseMessage> никогда не возвращает

public class ValidationFilter : IActionFilter 
{ 
    public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext context, 
                CancellationToken cancellationToken, 
              Func<Task<HttpResponseMessage>> continuation) 
    { 
     if(!actionContext.ModelState.IsValid) 
     { 
      return new Task<HttpResponseMessage>(() => 
        actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, 
                  actionContext.ModelState); 
     } 
     return continuation(); 
    } 
} 

Теперь, по какой-то причине, любой запрос с государственной ошибкой модели никогда не возвращает. Он просто висит там. Если я отладки, я получаю следующий фильтр в трубопроводе, который начинается с

var result = await continuation(); 

Если я «Шаг За» этой строки, отладчик вроде выбывает в режим «ожидания», но не больше код не кажется для запуска.

Я предполагаю, что все это потому, что я как-то неправильно понял, как все эти вещи взаимодействуют, но, несмотря на часы работы в Интернете и чтения, я до сих пор не могу понять, как правильно это сделать. Любая помощь - как для понимания, так и для исправления ошибок - глубоко ценится.

ответ

6

Вы никогда не начинаете свою задачу. Вам нужно позвонить Start, когда вы используете конструктор Task. Вместо вызова конструктора, а затем Start лучший вариантом был бы использовать Task.Run:

if(!actionContext.ModelState.IsValid) 
{ 
    return Task.Run(() => 
      actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, 
                actionContext.ModelState); 
} 

В вашем случае нет ничего действительно асинхронного о вашей работе, так что вы можете просто использовать Task.FromResult, чтобы создать задачу с результатом вы получаете синхронно:

public Task<HttpResponseMessage> ExecuteActionFilterAsync(
    HttpActionContext context, 
    CancellationToken cancellationToken, 
    Func<Task<HttpResponseMessage>> continuation) 
{ 
    if(!actionContext.ModelState.IsValid) 
    { 
     return Task.FromResult(actionContext.Request.CreateErrorResponse(
      HttpStatusCode.BadRequest, 
      actionContext.ModelState); 
    } 
    return continuation(); 
} 
+0

Спасибо - я (неправомерно) предположил, что каркас позаботится об этом для меня. –

+1

@ ТомасЛюкен уверен. Взгляните на мое обновление. – i3arnon

+0

Вы не хотите использовать 'Task.Run' внутри WebAPI, [его опасно] (http://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html) –

 Смежные вопросы

  • Нет связанных вопросов^_^