2012-03-29 30 views
11

Tôi đang thêm định tuyến ASP.NET vào ứng dụng webforms cũ hơn. Tôi đang sử dụng tùy chỉnh HttpHandler để xử lý mọi thứ. Trong một số trường hợp, tôi muốn ánh xạ một đường dẫn cụ thể trở lại một tệp aspx, vì vậy tôi cần phải chuyển quyền kiểm soát trở lại HttpHandler mặc định cho asp.net.Gọi asp.net HttpHandler mặc định từ trình xử lý tùy chỉnh

Gần nhất tôi đã nhận được là này

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 
} 

Nó không làm bất cứ điều gì, không có gì đầu ra cho dòng. Tài liệu của MS cho System.Web.UI.Page (như là một IHttpHandler) nói điều gì đó về hiệu ứng của "không gọi phương thức ProcessRequest. Nó dùng để sử dụng nội bộ."

Nhìn xung quanh, có vẻ như bạn có thể làm điều này với MVC, ví dụ: : MvcHttpHandler doesn't seem to implement IHttpHandler

Ngoài ra còn có điều này System.Web.UI.PageHandlerFactory xuất hiện rằng nó sẽ chỉ tạo Trình xử lý trang cho tệp aspx, nhưng nội bộ và tôi không thể sử dụng trực tiếp.

Trang này: http://msdn.microsoft.com/en-us/library/bb398986.aspx đề cập đến "trình xử lý asp.net mặc định" nhưng không xác định một lớp học hoặc đưa ra bất kỳ chỉ dẫn nào về cách người dùng có thể sử dụng nó.

Bất kỳ ý tưởng nào về cách tôi có thể thực hiện việc này? Có thể không?

Trả lời

6

Tính kiên trì sẽ được đền đáp! Điều này thực sự hoạt động, và vì thông tin này dường như có sẵn khá nhiều nơi tôi nghĩ tôi sẽ trả lời câu hỏi của riêng mình. Nhờ Robert cho bài viết này trên instantiating điều với các nhà thầu nội bộ, đây là chìa khóa.

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); 
} 

... và như một số phép lạ nhỏ, một trang aspx xử lý & làm cho hoàn toàn trong quá trình mà không cần phải chuyển hướng.

Tôi hy vọng điều này sẽ chỉ hoạt động trong IIS7.

1

Tôi đang sử dụng Định tuyến trong biểu mẫu web, bạn sẽ có thể chỉ cần thêm tuyến đường bỏ qua cho các tệp .aspx cụ thể mà bạn muốn. Điều này sau đó sẽ được xử lý bởi HttpHandler mặc định.

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

+0

Tôi đang cố gắng ánh xạ tuyến đường khác đến tệp, ví dụ: Tôi muốn "/ a/b/c" để gọi "default.aspx? Path = a/b/c" mà không cần chuyển hướng. Tôi đã bỏ qua * .aspx. –

+0

+1 vì không quá phức tạp. Chuyển hướng không phải là vấn đề lớn. Cộng với câu trả lời của bạn là rất tốt cho các thuật ngữ tìm kiếm google chung chung hơn mà đưa bạn đến trang này. – Thabo

0

Một tùy chọn khác là đảo ngược logic bằng cách xử lý các trường hợp mà bạn KHÔNG muốn trả về phản hồi mặc định và remap những người khác vào IHttpHandler của riêng bạn. Bất cứ khi nào myCondition là sai, phản hồi sẽ là "mặc định". Công tắc được triển khai dưới dạng 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; } 
} 
Các vấn đề liên quan