Merge pull request #1336 from esdrubal/datatablereadxmlschema
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / HttpHandlerUtil.cs
1 namespace System.Web.Mvc {
2     using System;
3     using System.Diagnostics.CodeAnalysis;
4     using System.Web;
5     using System.Web.Mvc.Resources;
6     using System.Web.UI;
7
8     internal static class HttpHandlerUtil {
9
10         // Since Server.Execute() doesn't propagate HttpExceptions where the status code is
11         // anything other than 500, we need to wrap these exceptions ourselves.
12         [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The Dispose on Page doesn't do anything by default, and we control both of these internal types.")]
13         public static IHttpHandler WrapForServerExecute(IHttpHandler httpHandler) {
14             IHttpAsyncHandler asyncHandler = httpHandler as IHttpAsyncHandler;
15             return (asyncHandler != null) ? new ServerExecuteHttpHandlerAsyncWrapper(asyncHandler) : new ServerExecuteHttpHandlerWrapper(httpHandler);
16         }
17
18         // Server.Execute() requires that the provided IHttpHandler subclass Page.
19         internal class ServerExecuteHttpHandlerWrapper : Page {
20             private readonly IHttpHandler _httpHandler;
21
22             public ServerExecuteHttpHandlerWrapper(IHttpHandler httpHandler) {
23                 _httpHandler = httpHandler;
24             }
25
26             internal IHttpHandler InnerHandler {
27                 get {
28                     return _httpHandler;
29                 }
30             }
31
32             public override void ProcessRequest(HttpContext context) {
33                 Wrap(() => _httpHandler.ProcessRequest(context));
34             }
35
36             protected static void Wrap(Action action) {
37                 Wrap(delegate {
38                     action();
39                     return (object)null;
40                 });
41             }
42
43             protected static TResult Wrap<TResult>(Func<TResult> func) {
44                 try {
45                     return func();
46                 }
47                 catch (HttpException he) {
48                     if (he.GetHttpCode() == 500) {
49                         throw; // doesn't need to be wrapped
50                     }
51                     else {
52                         HttpException newHe = new HttpException(500, MvcResources.ViewPageHttpHandlerWrapper_ExceptionOccurred, he);
53                         throw newHe;
54                     }
55                 }
56             }
57         }
58
59         private sealed class ServerExecuteHttpHandlerAsyncWrapper : ServerExecuteHttpHandlerWrapper, IHttpAsyncHandler {
60             private readonly IHttpAsyncHandler _httpHandler;
61
62             public ServerExecuteHttpHandlerAsyncWrapper(IHttpAsyncHandler httpHandler)
63                 : base(httpHandler) {
64                 _httpHandler = httpHandler;
65             }
66
67             public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
68                 return Wrap(() => _httpHandler.BeginProcessRequest(context, cb, extraData));
69             }
70
71             public void EndProcessRequest(IAsyncResult result) {
72                 Wrap(() => _httpHandler.EndProcessRequest(result));
73             }
74         }
75
76     }
77 }