Created
November 5, 2012 13:35
-
-
Save MikeJansen/4017214 to your computer and use it in GitHub Desktop.
Custom IHttpActionSelector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Radar.Common.WebServer.Api.Controllers | |
{ | |
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using System.Web.Http.Controllers; | |
using System.Web.Http.Filters; | |
public class DelegatingActionDescriptor: HttpActionDescriptor | |
{ | |
private readonly string _actionName; | |
private readonly HttpActionDescriptor _originalActionDescriptor; | |
public DelegatingActionDescriptor(string actionName, HttpActionDescriptor originalActionDescriptor) | |
{ | |
_actionName = actionName; | |
_originalActionDescriptor = originalActionDescriptor; | |
} | |
public override string ActionName | |
{ | |
get { return _actionName; } | |
} | |
public override Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, System.Threading.CancellationToken cancellationToken) | |
{ | |
return _originalActionDescriptor.ExecuteAsync(controllerContext, arguments, cancellationToken); | |
} | |
public override Collection<HttpParameterDescriptor> GetParameters() | |
{ | |
return _originalActionDescriptor.GetParameters(); | |
} | |
public override Type ReturnType | |
{ | |
get { return _originalActionDescriptor.ReturnType; } | |
} | |
public override HttpActionBinding ActionBinding | |
{ | |
get | |
{ | |
return _originalActionDescriptor.ActionBinding; | |
} | |
set | |
{ | |
_originalActionDescriptor.ActionBinding = value; | |
} | |
} | |
public override bool Equals(object obj) | |
{ | |
return _originalActionDescriptor.Equals(obj); | |
} | |
public override Collection<T> GetCustomAttributes<T>() | |
{ | |
return _originalActionDescriptor.GetCustomAttributes<T>(); | |
} | |
public override Collection<FilterInfo> GetFilterPipeline() | |
{ | |
return _originalActionDescriptor.GetFilterPipeline(); | |
} | |
public override Collection<IFilter> GetFilters() | |
{ | |
return _originalActionDescriptor.GetFilters(); | |
} | |
public override int GetHashCode() | |
{ | |
return _originalActionDescriptor.GetHashCode(); | |
} | |
public override ConcurrentDictionary<object, object> Properties | |
{ | |
get | |
{ | |
return _originalActionDescriptor.Properties; | |
} | |
} | |
public override IActionResultConverter ResultConverter | |
{ | |
get | |
{ | |
return _originalActionDescriptor.ResultConverter; | |
} | |
} | |
public override Collection<HttpMethod> SupportedHttpMethods | |
{ | |
get | |
{ | |
return _originalActionDescriptor.SupportedHttpMethods; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Web.Http; | |
using System.Web.Http.Controllers; | |
using System.Web.Mvc; | |
using System.Web.Optimization; | |
using System.Web.Routing; | |
using CommonFramework.Container; | |
using Radar.Common.Server; | |
using Radar.Common.Server.Container; | |
using Radar.Common.WebServer.Api; | |
using Radar.Common.WebServer.Api.Controllers; | |
using Radar.Common.WebServer.Api.Formatting; | |
namespace Radar.Api | |
{ | |
// Note: For instructions on enabling IIS6 or IIS7 classic mode, | |
// visit http://go.microsoft.com/?LinkId=9394801 | |
public class WebApiApplication : System.Web.HttpApplication | |
{ | |
protected void Application_Start() | |
{ | |
IContainerManager cm = RadarServerContainer.Initialize(ApplicationKeys.ApiKey); | |
GlobalConfiguration.Configuration.DependencyResolver = new RadarDependencyResolver(cm); | |
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; | |
AreaRegistration.RegisterAllAreas(); | |
WebApiConfig.Register(GlobalConfiguration.Configuration); | |
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); | |
RouteConfig.RegisterRoutes(RouteTable.Routes); | |
BundleConfig.RegisterBundles(BundleTable.Bundles); | |
// <<<<<< ------ HERE ------ >>>>>> | |
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector), new JsonpCorsActionSelector()); | |
GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Radar.Common.WebServer.Api.Controllers | |
{ | |
using System.Net.Http; | |
using System.Web.Http.Controllers; | |
public class JsonpCorsActionSelector : ApiControllerActionSelector | |
{ | |
private static readonly string HttpMethodQueryParameter = "httpMethod"; | |
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext) | |
{ | |
string httpMethod = controllerContext.Request.RequestUri.ParseQueryString()[HttpMethodQueryParameter]; | |
if (httpMethod != null) | |
{ | |
HttpRequestMessage originalRequest = controllerContext.Request; | |
HttpRequestMessage modifiedRequest = new HttpRequestMessage( | |
new HttpMethod(httpMethod), | |
originalRequest.RequestUri); | |
controllerContext.Request = modifiedRequest; | |
HttpActionDescriptor actualDescriptor = base.SelectAction(controllerContext); | |
controllerContext.Request = originalRequest; | |
return new DelegatingActionDescriptor(httpMethod, actualDescriptor); | |
} | |
return base.SelectAction(controllerContext); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Radar.Common.WebServer.Api.Formatting | |
{ | |
using System; | |
using System.IO; | |
using System.Net; | |
using System.Net.Http; | |
using System.Net.Http.Formatting; | |
using System.Net.Http.Headers; | |
using System.Threading.Tasks; | |
/// <summary> | |
/// | |
/// </summary> | |
/// <remarks> | |
/// Based on: | |
/// https://raw.github.com/gist/2967547/2ba629cdfa316348483aca53613d19fc3154f37d/JsonpFormatter.cs | |
/// http://www.matlus.com/jsonpmediatypeformatter-web-api-jsonp/ | |
/// </remarks> | |
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter | |
{ | |
private readonly string _callbackQueryParameter; | |
public JsonpMediaTypeFormatter(string callbackQueryParameter) | |
{ | |
_callbackQueryParameter = callbackQueryParameter ?? "callback"; | |
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); | |
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); | |
} | |
public JsonpMediaTypeFormatter() : this(null) { } | |
private string CallbackFunction { get; set; } | |
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext) | |
{ | |
var isJsonp = !string.IsNullOrEmpty(CallbackFunction); | |
return Task.Factory.StartNew(() => | |
{ | |
using (StreamWriter streamWriter = new StreamWriter(writeStream)) | |
{ | |
if (isJsonp) | |
{ | |
streamWriter.Write(CallbackFunction + "("); | |
streamWriter.Flush(); | |
} | |
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait(); | |
if (isJsonp) | |
{ | |
streamWriter.Write(")"); | |
streamWriter.Flush(); | |
} | |
} | |
}); | |
} | |
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType) | |
{ | |
var formatter = new JsonpMediaTypeFormatter(_callbackQueryParameter) | |
{ | |
CallbackFunction = GetJsonCallbackFunction(request) | |
}; | |
return formatter; | |
} | |
private string GetJsonCallbackFunction(HttpRequestMessage request) | |
{ | |
if (request.Method != HttpMethod.Get) return null; | |
var query = request.RequestUri.ParseQueryString(); | |
var queryVal = query[_callbackQueryParameter]; | |
if (string.IsNullOrEmpty(queryVal)) return null; | |
return queryVal; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment