diff --git a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/JsonpFormatter.cs b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/JsonpFormatter.cs new file mode 100644 index 0000000..a078476 --- /dev/null +++ b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/JsonpFormatter.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Formatting; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using Newtonsoft.Json.Converters; + +namespace WindowsDataCenter +{ + /// + /// Handles JsonP requests when requests are fired with text/javascript + /// + public class JsonpFormatter : JsonMediaTypeFormatter + { + + public JsonpFormatter() + { + SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); + SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); + + JsonpParameterName = "callback"; + } + + /// + /// Name of the query string parameter to look for + /// the jsonp function name + /// + public string JsonpParameterName { get; set; } + + /// + /// Captured name of the Jsonp function that the JSON call + /// is wrapped in. Set in GetPerRequestFormatter Instance + /// + private string JsonpCallbackFunction; + + + public override bool CanWriteType(Type type) + { + return true; + } + + /// + /// Override this method to capture the Request object + /// + /// + /// + /// + /// + public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType) + { + var formatter = new JsonpFormatter() + { + JsonpCallbackFunction = GetJsonCallbackFunction(request) + }; + + // this doesn't work unfortunately + //formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings; + + // You have to reapply any JSON.NET default serializer Customizations here + formatter.SerializerSettings.Converters.Add(new StringEnumConverter()); + formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; + + return formatter; + } + + public override Task WriteToStreamAsync( + Type type, + object value, + Stream stream, + HttpContent content, + TransportContext transportContext + ) + { + if (string.IsNullOrEmpty(JsonpCallbackFunction)) + { + return base.WriteToStreamAsync(type, value, stream, content, transportContext); + } + + // write the JSONP pre-amble + var preamble = Encoding.ASCII.GetBytes(JsonpCallbackFunction + "("); + stream.Write(preamble, 0, preamble.Length); + + return base.WriteToStreamAsync(type, value, stream, content, transportContext).ContinueWith((innerTask, state) => + { + if (innerTask.Status == TaskStatus.RanToCompletion) + { + // write the JSONP suffix + var responseStream = (Stream)state; + var suffix = Encoding.ASCII.GetBytes(")"); + responseStream.Write(suffix, 0, suffix.Length); + } + }, stream, TaskContinuationOptions.ExecuteSynchronously); + } + //public override Task WriteToStreamAsync( + // Type type, + // object value, + // Stream stream, + // HttpContent content, + // TransportContext transportContext) + //{ + // if (string.IsNullOrEmpty(JsonpCallbackFunction)) + // return base.WriteToStreamAsync(type, value, stream, content, transportContext); + + // StreamWriter writer = null; + + // // write the pre-amble + // try + // { + // writer = new StreamWriter(stream); + // writer.Write(JsonpCallbackFunction + "("); + // writer.Flush(); + // } + // catch (Exception ex) + // { + // try + // { + // if (writer != null) + // writer.Dispose(); + // } + // catch { } + + // var tcs = new TaskCompletionSource(); + // tcs.SetException(ex); + // return tcs.Task; + // } + + // return base.WriteToStreamAsync(type, value, stream, content, transportContext) + // .ContinueWith(innerTask => + // { + // if (innerTask.Status == TaskStatus.RanToCompletion) + // { + // writer.Write(")"); + // writer.Flush(); + // } + + // }, TaskContinuationOptions.ExecuteSynchronously) + // .ContinueWith(innerTask => + // { + // writer.Dispose(); + // return innerTask; + + // }, TaskContinuationOptions.ExecuteSynchronously) + // .Unwrap(); + //} + + /// + /// Retrieves the Jsonp Callback function + /// from the query string + /// + /// + private string GetJsonCallbackFunction(HttpRequestMessage request) + { + if (request.Method != HttpMethod.Get) + return null; + + var query = HttpUtility.ParseQueryString(request.RequestUri.Query); + var queryVal = query[this.JsonpParameterName]; + + if (string.IsNullOrEmpty(queryVal)) + return null; + + return queryVal; + } + } +} diff --git a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Service1.cs b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Service1.cs index 6c74fff..86c7607 100644 --- a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Service1.cs +++ b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Service1.cs @@ -69,18 +69,9 @@ namespace WindowsDataCenter } } } - public class StartOwin { - public void Configuration(IAppBuilder appBuilder) { - var config = new HttpConfiguration(); - config.Routes.MapHttpRoute( - name: "DefaultApi", - routeTemplate: "api/{controller}/{id}", - defaults: new { id = RouteParameter.Optional } - ); - appBuilder.UseWebApi(config); } } diff --git a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/StartOwin.cs b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/StartOwin.cs new file mode 100644 index 0000000..2534fe2 --- /dev/null +++ b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/StartOwin.cs @@ -0,0 +1,24 @@ +using System.Web.Http; +using Owin; + +namespace WindowsDataCenter +{ + public class StartOwin + { + public void Configuration(IAppBuilder appBuilder) + { + var config = new HttpConfiguration(); + //config.Routes.MapHttpRoute( + // name: "DefaultApi", + // routeTemplate: "api/{controller}/{id}", + // defaults: new { id = RouteParameter.Optional } + //); + config.MapHttpAttributeRoutes(); + + config.Formatters.Insert(0, new JsonpFormatter()); + + + appBuilder.UseWebApi(config); + } + } +} \ No newline at end of file