2013-02-05 10 views
13

Mam ciekawy przypadek nie mogę wyjaśnić, a ja potrzebuję pomocy na zastanawianie się, co mój problem polega na IIS7:ASP.NET MVC4 nie obsługuje żądania POST w trybie zintegrowanym IIS7, ale w IIS7.5

Dane:

  • aplikacji ASP.NET MVC 4 internetowej
  • domyślna trasa zarejestrowana {kontroler}/{akcja}

Zobacz następujący kontroler:

public class ServiceController : Controller 
{ 
    public ActionResult Test() 
    { 
     return Content("Test"); 
    } 

    [HttpPost] 
    public ActionResult Test2() 
    { 
     return Content("Test2"); 
    } 
} 

Dodatkowo w Global.asax nie jest to kod:

protected void Application_EndRequest() 
{ 
    if (Context.Response.StatusCode == 404) 
    { 
     ExecuteIndexPage(); 
    } 
} 

protected void Application_Error(object sender, EventArgs e) 
{ 
    var error = Server.GetLastError(); 
    ExceptionLogger.Log(error); 

    ExecuteIndexPage(); 
} 

Tak więc, gdy wystąpi błąd serwera, to jest rejestrowane. W tym przypadku i w przypadku normalnego 404 strona początkowa jest zwracana. To działa (prawie) dobrze. Więcej do tego później.

Ta konfiguracja zapewnia bardzo różne zachowania na IIS7 (Windows Server 2008, środowisko produkcyjne) i IIS7.5 (Win7 Pro, środowisko programistyczne i Windows Server 2008 R2, a także środowisko produkcyjne).

Biorąc pod uwagę następującą konfigurację IIS (obie wersje):

  • Web w IIS jest skonfigurowany przy użyciu zintegrowany tryb ASP.NET basen 4 aplikacja
  • < moduły runAllManagedModulesForAllRequests = "true"/> jest ustawione w sekcji system.webServer

W IIS 7.5 zachowanie to:

  • żądanie GET do /: Zwraca strony indeksu prośba
  • POST /: Zwraca strony indeksu
  • GET Żądanie/Serwis/Test: Zwraca test
  • żądanie POST do/usługa/test : Zwraca Przetestuj
  • GET żądanie do/usługa/Test2: Wykonuje Global.asax Application_Error: HttpException: metoda działania publiczne 'Test2' nie została znaleziona w kontrolerze 'MyTestProject.Controllers.ServiceController'.
  • żądanie POST/usługa/Test2: Zwraca test2
  • żądanie GET do czegoś jest nie droga: Wykonuje global.asax End_Request.

W IIS 7 zachowanie zamiast to: wniosek

  • GET do /: strona indeksu
  • żądanie POST wraca do /: IIS 404
  • GET Żądanie/Serwis/Test: Zwroty Test
  • Zapytanie do/Usługa/Test: IIS 404 strona
  • GET Request to/Service/Test2: Wykonuje Global.asax Application_Error: HttpException: Publiczna metoda działania "Test2" nie została znaleziona na kontrolerze "MyTestProject.Controllers.ServiceController".
  • POST Żądanie/usługa/Test2: Zwraca IIS stronę 404
  • żądanie GET do czegoś istnieje nie droga: IIS 404

Tak, IIS 7 i IIS 7.5 doskonale podczas korzystania Żądania GET, z wyjątkiem sytuacji, gdy nie ma trasy. Gdy nie ma trasy, IIS 7.5 wykonuje żądanie końca Global.asax o kodzie statusu 404 i dostarcza stronę indeksu. IIS 7 ma NOT wykonać żądanie końca Global.asax. Czemu? Mogę (i obecnie robię) obejść ten problem, rejestrując trasę {* catchall}, aby znaleźć pasującą trasę.

Jak tylko próbuję korzystać z HTTP POST, IIS 7 działa jeszcze mniej niż powinienem oczekiwać.

Podczas wysyłania żądania, IIS 7 nie wykonuje żadnego kodu w mojej aplikacji i bezpośrednio zwraca stronę IIS 404.

Moje pytanie brzmi: dlaczego IIS 7 odmawia tak trudnego traktowania wniosków POST w mojej aplikacji MVC 4, i co mogę zrobić, aby obsłużyć żądanie postu?

Odpowiedz

1

Ustaliliśmy to - w końcu.

Wkładki Domyślna konfiguracja to w pliku web.config:

<system.webServer> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <modules runAllManagedModulesForAllRequests="true" /> 
    <handlers> 
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> 
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> 
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
</system.webServer> 

Problemem jest "*". ścieżka, która obejmowałaby /test.aspx, ale nie po prostu/test.

Jeśli zmienisz to na "*", wszystkie żądania będą obsługiwane przez ExtensionlessUrlHandler, w tym te do plików statycznych, które nie będą już wyświetlane.

Więc rozwiązanie jest: Usuń czasownika POST z zapisami przewodnika i dodawać nowe wpisy dla ExtensionlessUrlHandler ze ścieżką ustawioną na „*” i tylko dla żądań POST:

<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0_post" path="*" verb="POST" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 

Idealnie usunąć te nie potrzebujesz (x86 i x64 w klasycznym vs zintegrowanym potoku).

0

Może to mieć związek z niektórymi funkcjami, które nie są (lub nie są poprawnie) zainstalowane w IIS 7, co uniemożliwia poprawne działanie URL-i.

proszę sprawdzić następujące elementy:

w "Włącz funkcje systemu Windows lub Off" okno Panelu sterowania systemu Windows "Programy i funkcje" application:

  1. Przejdź do Internet Information Services> Usługi World Wide Web> Typowe funkcje HTTP
  2. Upewnij się, że wybrana jest opcja "Przekierowanie błędu HTTP".
  3. Upewnij się, że wybrana jest opcja "Kompresja zawartości statycznej". Po wybraniu dowolnej opcji kliknij "OK", aby zapisać zmiany.

referencyjny: http://support.microsoft.com/kb/2023146

0

Może 7 i 7,5 routingu są różne w odniesieniu do oddaniem POST do działań, które nie ma żadnego argumentu, który może akceptować dane formularza postu.

Jeśli twój kod nigdy nie zostanie trafiony, oznacza to, że routing nie znalazł dopasowania do podpisu, argumentów i wbudowanych więzów, które sprawdza przed przekazaniem kodu.

Może następnym krokiem będzie dodanie argumentu do POST, aby zaakceptować model, nawet jeśli nie przekazujesz tego modelu. W rezultacie model będzie oczywiście zerowy.