2012-03-29 10 views
11

Dodaję routing ASP.NET do starszej aplikacji do obsługi formularzy internetowych. Używam niestandardowego HttpHandler do przetwarzania wszystkiego. W niektórych sytuacjach chciałbym zmapować określoną ścieżkę z powrotem do pliku aspx, więc muszę po prostu przekazać kontrolę do domyślnego HttpHandler dla asp.net.Wywołanie domyślnego programu obsługi stron WWW asp.net HttpHandler z niestandardowego programu obsługi

Najbliżej stałam jest to

public void ProcessRequest(HttpContext context) { 
    // .. when we decide to pass it on 

    var handler = new System.Web.UI.Page(); 
    handler.ProcessRequest(context); 

    MemoryStream steam = new MemoryStream(); 
    StreamWriter writer = new StreamWriter(stream); 
    HtmlTextWriter htmlWriter = new HtmlTextWriter(writer); 
    handler.RenderControl(htmlWriter); 


    // write headers, etc. & send stream to Response 
} 

To nic nie robi, nie ma nic do strumienia wyjściowego. Dokumentacja MS dla System.Web.UI.Page (jako IHttpHandler) mówi coś do skutku "nie wywołuj metody ProcessRequest. Jest do użytku wewnętrznego."

Wygląda na to, że można to zrobić za pomocą MVC, np. : MvcHttpHandler doesn't seem to implement IHttpHandler

Jest też coś, co wydaje się, że po prostu tworzy procedurę obsługi stron dla pliku aspx, ale jest wewnętrzna i nie mogę jej użyć bezpośrednio.

Ta strona: http://msdn.microsoft.com/en-us/library/bb398986.aspx odnosi się do "domyślnego programu obsługi asp.net", ale nie identyfikuje klasy ani nie wskazuje, w jaki sposób można jej użyć.

Jakieś pomysły na to, jak mogę to zrobić? Czy to możliwe?

Odpowiedz

6

Trwałość się opłaca! To faktycznie działa, a ponieważ ta informacja wydaje się być dostępna prawie nigdzie, myślałem, że odpowiem na własne pytanie. Dzięki Robertowi za ten post na temat tworzenia wystąpień z wewnętrznymi konstruktorami, to jest klucz.

http://www.rvenables.com/2009/08/instantiating-classes-with-internal-constructors/

public void ProcessRequest(HttpContext context) { 
    // the internal constructor doesn't do anything but prevent you from instantiating 
    // the factory, so we can skip it. 
    PageHandlerFactory factory = 
     (PageHandlerFactory)System.Runtime.Serialization.FormatterServices 
     .GetUninitializedObject(typeof(System.Web.UI.PageHandlerFactory)); 

    string newTarget = "default.aspx"; 
    string newQueryString = // whatever you want 
    string oldQueryString = context.Request.QueryString.ToString(); 
    string queryString = newQueryString + oldQueryString!="" ? 
     "&" + newQueryString : 
     ""; 

    // the 3rd parameter must be just the file name. 
    // the 4th parameter should be the physical path to the file, though it also 
    // works fine if you pass an empty string - perhaps that's only to override 
    // the usual presentation based on the path? 

    var handler = factory.GetHandler(context, "GET",newTarget, 
     context.Request.MapPath(context,newTarget)); 

    // Update the context object as it should appear to your page/app, and 
    // assign your new handler. 

    context.RewritePath(newTarget , "", queryString); 
    context.Handler = handler; 

    // .. and done 

    handler.ProcessRequest(context); 
} 

... a jak jakiś mały cud, strony aspx przetwarza & oddaje całkowicie w procesie bez konieczności przekierowania.

Oczekuję, że będzie działać tylko w IIS7.

1

Używasz routingu w formularzach sieciowych, powinieneś móc dodać trasę ignorowania dla konkretnych plików .aspx, które chcesz. To będzie obsługiwane przez domyślny HttpHandler.

http://msdn.microsoft.com/en-us/library/dd505203.aspx

+0

Próbuję odwzorować inną trasę do pliku, np. Chcę "/ a/b/c" wywołać "default.aspx? Ścieżka = a/b/c" bez przekierowania. Ignoruję już * .aspx. –

+0

+1 za nadmierne komplikowanie. Przekierowania to nic wielkiego. Dodatkowo twoja odpowiedź jest świetna dla bardziej ogólnych haseł wyszukiwania w Google, które prowadzą do tej strony. – Thabo

0

Inną opcją jest odwrócenie logiki poprzez obsługę przypadków, w których NIE chcesz zwrócić domyślnej odpowiedzi i zamapować innych na własny IHttpHandler. Ilekroć myCount jest fałszywy, odpowiedź będzie "domyślna". Przełącznik jest zaimplementowany jako moduł IHttpModule:

public class SwitchModule: IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.PostAuthenticateRequest += app_PostAuthenticateRequest; 
    } 

    void app_PostAuthenticateRequest(object sender, EventArgs e) 
    { 
     // Check for whatever condition you like   
     if (true) 
      HttpContext.Current.RemapHandler(new CustomHandler()); 

    } 

    public void Dispose()   
} 

internal class CustomHandler: IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     context.Response.Write("hallo"); 
    } 

    public bool IsReusable { get; } 
} 
Powiązane problemy