2013-08-20 13 views
7

Powiązane pytanie: Web API action parameter is intermittently null i http://social.msdn.microsoft.com/Forums/vstudio/en-US/25753b53-95b3-4252-b034-7e086341ad20/web-api-action-parameter-is-intermittently-nullnie można odczytać

Hi!

Tworzę ActionFilterAttribute w ASP.NET MVC WebAPI 4 więc mogę zastosować atrybut w metodach działania na kontrolerze, które musimy walidacji z tokena przed wykonaniem go jako poniższego kodu:

public class TokenValidationAttribute : ActionFilterAttribute 
{ 
     public override void OnActionExecuting(HttpActionContext filterContext) 
     { 
     //Tried this way 
     var result = string.Empty; 
     filterContext.Request.Content.ReadAsStringAsync().ContinueWith((r)=> content = r.Result); 

     //And this 
     var result = filterContext.Request.Content.ReadAsStringAsync().Result; 

     //And this 
     var bytes = await request.Content.ReadAsByteArrayAsync().Result; 
     var str = System.Text.Encoding.UTF8.GetString(bytes); 

     //omit the other code that use this string below here for simplicity 
    } 
} 

Próbuję odczytać zawartość jako ciąg znaków. Wypróbowałem 3 sposoby, jak podano w tym kodzie, a wszystkie z nich wracają puste. Wiem, że w WebApi mogę przeczytać tylko raz zawartość treści żądania, więc komentuję wszystko inne w kodzie i próbuję go uruchomić, aby sprawdzić, czy otrzymuję wynik. Chodzi o to, że klient, a nawet Fiddler, zgłasza 315 długości treści żądania. Ten sam rozmiar trafia również do nagłówka zawartości serwera, ale gdy próbujemy odczytać zawartość, jest ona pusta.

Po usunięciu atrybutu i zrobieniu tego samego żądania, kontroler nazywa się dobrze, a deserializacja Jsona odbywa się bezbłędnie. Jeśli umieściłem atrybut, wszystko, co otrzymam, jest pustym ciągiem z treści. Zdarza się ZAWSZE. Nie przerywane, jak twierdzą powiązane pytania.

Co robię źle? Należy pamiętać, że używam ActionFilter zamiast DelegatingHandler, ponieważ tylko wybrane akcje wymagają sprawdzenia tokenu przed wykonaniem.

Dzięki za pomoc! Bardzo to doceniam.

Pozdrawiam ...

Gutemberg

Odpowiedz

15

Domyślnie polityka bufor dla Web Host (IIS) scenariuszy jest to, że strumień na przychodzące żądanie jest zawsze buforowane. Możesz spojrzeć na System.Web.Http.WebHost.WebHostBufferPolicySelector. Teraz, jak się domyślacie, formatery Web Api pochłoną strumień i nie będą próbowały go zawinąć. Jest to celowe, ponieważ można zmienić zasady bufora, aby strumień przychodzącego żądania nie był buforowany, w którym to przypadku przewijanie zakończyłoby się niepowodzeniem.

W twoim przypadku, ponieważ wiesz, że żądanie będzie zawsze buforowane, możesz pobrać przychodzący strumień jak poniżej i przewinąć go do tyłu.

Stream reqStream = await request.Content.ReadAsStreamAsync(); 

if(reqStream.CanSeek) 
{ 
    reqStream.Position = 0; 
} 

//now try to read the content as string 
string data = await request.Content.ReadAsStringAsync(); 
+0

Dzięki za odpowiedź. Teraz zadziałało, jak kazałeś Kiranowi. Chodzi o to, że nadal nie jestem do końca pewien, dlaczego tak się dzieje ... Mam ten sam kod uruchomiony w innym projekcie i teraz dostaję ten problem ... –

+0

No ale teraz mam inny problem. Nie mogę tego zrobić asynchronicznie. Ponieważ struktura nie nazywa tego asynchronicznie, a przepływ wykonania wywołuje działanie kontrolera przed zakończeniem działania OnActionExecuting() ... –

+0

Moja zła! Zawsze mogę użyć .Result po metodach Async(), więc wątek będzie trwał do zakończenia wykonywania metody. Wszystko teraz dobrze się układało. Dzięki jeszcze raz! –

Powiązane problemy