Permalink
Browse files

349089: Fixing the issue where HttpMethodConstraint does not work for…

… WebAPI on Web Host
  • Loading branch information...
1 parent c28443a commit 590ee02f487fd0f2d7822f210d9e564ab6d4db62 yaohuang committed Apr 2, 2012
@@ -138,7 +138,7 @@ protected virtual void ProcessRequest(HttpContextBase httpContextBase)
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Object gets passed to a task")]
protected virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContextBase, AsyncCallback callback, object state)
{
- HttpRequestMessage request = ConvertRequest(httpContextBase);
+ HttpRequestMessage request = httpContextBase.GetHttpRequestMessage() ?? ConvertRequest(httpContextBase);
// Add route data
request.Properties[HttpPropertyKeys.HttpRouteDataKey] = _routeData;
@@ -356,7 +356,7 @@ internal static bool IsOutputBufferingNecessary(HttpContent httpContent)
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Caller becomes owner")]
- private static HttpRequestMessage ConvertRequest(HttpContextBase httpContextBase)
+ internal static HttpRequestMessage ConvertRequest(HttpContextBase httpContextBase)
{
Contract.Assert(httpContextBase != null);
@@ -384,12 +384,12 @@ private static HttpRequestMessage ConvertRequest(HttpContextBase httpContextBase
/// setting <see cref="P:System.Web.HttpResponseBase.SuppressFormsAuthenticationRedirect" /> to <c>true</c> if available.
/// </summary>
/// <param name="httpContextBase">The HTTP context base.</param>
- internal static void EnsureSuppressFormsAuthenticationRedirect(HttpContextBase httpContextBase)
+ internal static void EnsureSuppressFormsAuthenticationRedirect(HttpContextBase httpContextBase)
{
Contract.Assert(httpContextBase != null);
// Only if the response is status code is 401
- if (httpContextBase.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
+ if (httpContextBase.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
_suppressRedirectAction.Value(httpContextBase);
}
@@ -0,0 +1,29 @@
+using System.Net.Http;
+
+namespace System.Web.Http.WebHost.Routing
+{
+ internal static class HttpContextBaseExtensions
+ {
+ internal static readonly string HttpRequestMessageKey = "MS_HttpRequestMessage";
+
+ public static HttpRequestMessage GetHttpRequestMessage(this HttpContextBase context)
+ {
+ if (context == null)
+ {
+ throw Error.ArgumentNull("context");
+ }
+
+ if (!context.Items.Contains(HttpRequestMessageKey))
+ {
+ return null;
+ }
+
+ return context.Items[HttpRequestMessageKey] as HttpRequestMessage;
+ }
+
+ public static void SetHttpRequestMessage(this HttpContextBase context, HttpRequestMessage request)
+ {
+ context.Items.Add(HttpRequestMessageKey, request);
+ }
+ }
+}
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Net.Http;
+using System.Web.Http.Routing;
using System.Web.Routing;
namespace System.Web.Http.WebHost.Routing
@@ -42,6 +44,24 @@ public HttpWebRoute(string url, RouteValueDictionary defaults, RouteValueDiction
{
}
+ protected override bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
+ {
+ IHttpRouteConstraint httpRouteConstraint = constraint as IHttpRouteConstraint;
+ if (httpRouteConstraint != null)
+ {
+ HttpRequestMessage request = httpContext.GetHttpRequestMessage();
+ if (request == null)
+ {
+ request = HttpControllerHandler.ConvertRequest(httpContext);
+ httpContext.SetHttpRequestMessage(request);
+ }
+
+ return httpRouteConstraint.Match(request, new HostedHttpRoute(this), parameterName, values, ConvertRouteDirection(routeDirection));
+ }
+
+ return base.ProcessConstraint(httpContext, constraint, parameterName, values, routeDirection);
+ }
+
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
// Only perform URL generation if the "httproute" key was specified. This allows these
@@ -70,5 +90,20 @@ private static RouteValueDictionary GetRouteDictionaryWithoutHttpRouteKey(IDicti
}
return newRouteValues;
}
+
+ private static HttpRouteDirection ConvertRouteDirection(RouteDirection routeDirection)
+ {
+ if (routeDirection == RouteDirection.IncomingRequest)
+ {
+ return HttpRouteDirection.UriResolution;
+ }
+
+ if (routeDirection == RouteDirection.UrlGeneration)
+ {
+ return HttpRouteDirection.UriGeneration;
+ }
+
+ throw Error.InvalidEnumArgument("routeDirection", (int)routeDirection, typeof(RouteDirection));
+ }
}
}
@@ -82,6 +82,7 @@
</Compile>
<Compile Include="PreApplicationStartCode.cs" />
<Compile Include="HttpControllerTypeCacheSerializer.cs" />
+ <Compile Include="Routing\HttpContextBaseExtensions.cs" />
<Compile Include="WebHostHttpControllerTypeResolver.cs" />
<Compile Include="Routing\HostedHttpRouteCollection.cs" />
<Compile Include="Routing\HostedHttpRoute.cs" />
@@ -123,7 +123,6 @@ public virtual Collection<HttpMethod> GetHttpMethodsSupportedByAction(IHttpRoute
throw Error.ArgumentNull("actionDescriptor");
}
- bool isActionVariableSpecified = _actionVariableRegex.IsMatch(route.RouteTemplate) || route.Defaults.ContainsKey(ActionVariableName);
IList<HttpMethod> supportedMethods = new List<HttpMethod>();
IList<HttpMethod> actionHttpMethods = actionDescriptor.SupportedHttpMethods;
HttpMethodConstraint httpMethodConstraint = route.Constraints.Values.FirstOrDefault(c => typeof(HttpMethodConstraint).IsAssignableFrom(c.GetType())) as HttpMethodConstraint;

0 comments on commit 590ee02

Please sign in to comment.