jsonp媒体类型格式化程序c#问题
可能是个愚蠢的问题,但我正在尝试将jsonp支持添加到我的webapi应用程序中。我将这一行添加到我的webapiconfig.cs中,但它失败了,因为jsonpmediatypeformatter构造函数需要两个参数:jsonp媒体类型格式化程序c#问题,c#,.net,asp.net-mvc,asp.net-mvc-4,jsonp,C#,.net,Asp.net Mvc,Asp.net Mvc 4,Jsonp,可能是个愚蠢的问题,但我正在尝试将jsonp支持添加到我的webapi应用程序中。我将这一行添加到我的webapiconfig.cs中,但它失败了,因为jsonpmediatypeformatter构造函数需要两个参数: public static void Register(HttpConfiguration configuration) { configuration.Routes.MapHttpRoute("API Default", "api/v1/{contr
public static void Register(HttpConfiguration configuration)
{
configuration.Routes.MapHttpRoute("API Default", "api/v1/{controller}/{id}",
new { id = RouteParameter.Optional });
var appXmlType = configuration.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
configuration.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
**configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter();**
}
第一个似乎是mediatypeformatter类型,这对我来说没有多大意义。我试过:
configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter(new JsonMediaTypeFormatter(),"jsonp"));
它确实将响应正确地包装在一个名为jsonp的函数中,但也破坏了标准json响应
有什么想法吗?所以,我读了很多关于向WebAPI添加JSONP支持的文章。我都试过了 然后,我花时间阅读了我一直在使用的常规Json格式化程序……嘿,它也支持Jsonp 下面是课堂:
public class JsonNetFormatter : MediaTypeFormatter
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
private string _callbackQueryParameter;
public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
//we also support jsonp.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
private Encoding Encoding
{
get { return SupportedEncodings[0]; }
}
public string CallbackQueryParameter
{
get { return _callbackQueryParameter ?? "callback"; }
set { _callbackQueryParameter = value; }
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request,
MediaTypeHeaderValue mediaType)
{
var formatter = new JsonNetFormatter(_jsonSerializerSettings)
{
JsonpCallbackFunction = GetJsonCallbackFunction(request)
};
return formatter;
}
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get)
return null;
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var queryVal = query[CallbackQueryParameter];
if (string.IsNullOrEmpty(queryVal))
return null;
return queryVal;
}
private string JsonpCallbackFunction { get; set; }
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(readStream, SupportedEncodings[0]))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var isJsonp = JsonpCallbackFunction != null;
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(writeStream, Encoding)) { CloseOutput = false })
{
if (isJsonp)
{
jsonTextWriter.WriteRaw(JsonpCallbackFunction + "(");
jsonTextWriter.Flush();
}
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
if (isJsonp)
{
jsonTextWriter.WriteRaw(")");
jsonTextWriter.Flush();
}
}
});
}
}
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
private string _callbackQueryParamter;
private HttpRequestMessage HttpRequest;
public JsonpMediaTypeFormatter()
{
SupportedMediaTypes.Add(DefaultMediaType);
SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
}
public string CallbackQueryParameter
{
get { return _callbackQueryParamter ?? "callback"; }
set { _callbackQueryParamter = value; }
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
HttpRequest = request;
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
string callback;
if (IsJsonpRequest(out callback))
{
return Task.Factory.StartNew(() =>
{
var writer = new StreamWriter(writeStream);
writer.Write(callback + "(");
writer.Flush();
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait();
writer.Write(")");
writer.Flush();
});
}
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
private bool IsJsonpRequest(out string callback)
{
var query = HttpUtility.ParseQueryString(HttpRequest.RequestUri.Query);
callback = query[CallbackQueryParameter];
return !string.IsNullOrEmpty(callback);
}
}
并从应用程序开始调用它
这对我来说非常有用,可以同时支持json和jsonp。因此,我读了大量关于向WebAPI添加jsonp支持的文章。我都试过了 然后,我花时间阅读了我一直在使用的常规Json格式化程序……嘿,它也支持Jsonp 下面是课堂:
public class JsonNetFormatter : MediaTypeFormatter
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
private string _callbackQueryParameter;
public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
//we also support jsonp.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
private Encoding Encoding
{
get { return SupportedEncodings[0]; }
}
public string CallbackQueryParameter
{
get { return _callbackQueryParameter ?? "callback"; }
set { _callbackQueryParameter = value; }
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request,
MediaTypeHeaderValue mediaType)
{
var formatter = new JsonNetFormatter(_jsonSerializerSettings)
{
JsonpCallbackFunction = GetJsonCallbackFunction(request)
};
return formatter;
}
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get)
return null;
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var queryVal = query[CallbackQueryParameter];
if (string.IsNullOrEmpty(queryVal))
return null;
return queryVal;
}
private string JsonpCallbackFunction { get; set; }
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(readStream, SupportedEncodings[0]))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var isJsonp = JsonpCallbackFunction != null;
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(writeStream, Encoding)) { CloseOutput = false })
{
if (isJsonp)
{
jsonTextWriter.WriteRaw(JsonpCallbackFunction + "(");
jsonTextWriter.Flush();
}
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
if (isJsonp)
{
jsonTextWriter.WriteRaw(")");
jsonTextWriter.Flush();
}
}
});
}
}
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
private string _callbackQueryParamter;
private HttpRequestMessage HttpRequest;
public JsonpMediaTypeFormatter()
{
SupportedMediaTypes.Add(DefaultMediaType);
SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
}
public string CallbackQueryParameter
{
get { return _callbackQueryParamter ?? "callback"; }
set { _callbackQueryParamter = value; }
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
HttpRequest = request;
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
string callback;
if (IsJsonpRequest(out callback))
{
return Task.Factory.StartNew(() =>
{
var writer = new StreamWriter(writeStream);
writer.Write(callback + "(");
writer.Flush();
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait();
writer.Write(")");
writer.Flush();
});
}
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
private bool IsJsonpRequest(out string callback)
{
var query = HttpUtility.ParseQueryString(HttpRequest.RequestUri.Query);
callback = query[CallbackQueryParameter];
return !string.IsNullOrEmpty(callback);
}
}
并从应用程序开始调用它
这对我来说非常有用,可以同时支持json和jsonp。我花了很长时间才让它工作起来。此代码基于-这对我不起作用,因为.NET framework的4.5版本
HttpContext.Current
返回null
这是一节课:
public class JsonNetFormatter : MediaTypeFormatter
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
private string _callbackQueryParameter;
public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
//we also support jsonp.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
private Encoding Encoding
{
get { return SupportedEncodings[0]; }
}
public string CallbackQueryParameter
{
get { return _callbackQueryParameter ?? "callback"; }
set { _callbackQueryParameter = value; }
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request,
MediaTypeHeaderValue mediaType)
{
var formatter = new JsonNetFormatter(_jsonSerializerSettings)
{
JsonpCallbackFunction = GetJsonCallbackFunction(request)
};
return formatter;
}
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get)
return null;
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var queryVal = query[CallbackQueryParameter];
if (string.IsNullOrEmpty(queryVal))
return null;
return queryVal;
}
private string JsonpCallbackFunction { get; set; }
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(readStream, SupportedEncodings[0]))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var isJsonp = JsonpCallbackFunction != null;
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(writeStream, Encoding)) { CloseOutput = false })
{
if (isJsonp)
{
jsonTextWriter.WriteRaw(JsonpCallbackFunction + "(");
jsonTextWriter.Flush();
}
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
if (isJsonp)
{
jsonTextWriter.WriteRaw(")");
jsonTextWriter.Flush();
}
}
});
}
}
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
private string _callbackQueryParamter;
private HttpRequestMessage HttpRequest;
public JsonpMediaTypeFormatter()
{
SupportedMediaTypes.Add(DefaultMediaType);
SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
}
public string CallbackQueryParameter
{
get { return _callbackQueryParamter ?? "callback"; }
set { _callbackQueryParamter = value; }
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
HttpRequest = request;
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
string callback;
if (IsJsonpRequest(out callback))
{
return Task.Factory.StartNew(() =>
{
var writer = new StreamWriter(writeStream);
writer.Write(callback + "(");
writer.Flush();
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait();
writer.Write(")");
writer.Flush();
});
}
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
private bool IsJsonpRequest(out string callback)
{
var query = HttpUtility.ParseQueryString(HttpRequest.RequestUri.Query);
callback = query[CallbackQueryParameter];
return !string.IsNullOrEmpty(callback);
}
}
这需要添加到您的启动中:
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
// Remove the XML formatter (only want JSON) see http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
config.Formatters.Remove(config.Formatters.XmlFormatter);
// add jsonp formatter as the one with the highest prio
config.Formatters.Insert(0, new JsonpMediaTypeFormatter());
// routes
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{arg1}/{arg2}",
defaults: new { arg1 = RouteParameter.Optional, arg2 = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
我也花了很长时间才让它工作起来。此代码基于-这对我不起作用,因为.NET framework的4.5版本
HttpContext.Current
返回null
这是一节课:
public class JsonNetFormatter : MediaTypeFormatter
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
private string _callbackQueryParameter;
public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
//we also support jsonp.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
private Encoding Encoding
{
get { return SupportedEncodings[0]; }
}
public string CallbackQueryParameter
{
get { return _callbackQueryParameter ?? "callback"; }
set { _callbackQueryParameter = value; }
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request,
MediaTypeHeaderValue mediaType)
{
var formatter = new JsonNetFormatter(_jsonSerializerSettings)
{
JsonpCallbackFunction = GetJsonCallbackFunction(request)
};
return formatter;
}
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get)
return null;
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var queryVal = query[CallbackQueryParameter];
if (string.IsNullOrEmpty(queryVal))
return null;
return queryVal;
}
private string JsonpCallbackFunction { get; set; }
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(readStream, SupportedEncodings[0]))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var isJsonp = JsonpCallbackFunction != null;
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(writeStream, Encoding)) { CloseOutput = false })
{
if (isJsonp)
{
jsonTextWriter.WriteRaw(JsonpCallbackFunction + "(");
jsonTextWriter.Flush();
}
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
if (isJsonp)
{
jsonTextWriter.WriteRaw(")");
jsonTextWriter.Flush();
}
}
});
}
}
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
private string _callbackQueryParamter;
private HttpRequestMessage HttpRequest;
public JsonpMediaTypeFormatter()
{
SupportedMediaTypes.Add(DefaultMediaType);
SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
}
public string CallbackQueryParameter
{
get { return _callbackQueryParamter ?? "callback"; }
set { _callbackQueryParamter = value; }
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
HttpRequest = request;
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
string callback;
if (IsJsonpRequest(out callback))
{
return Task.Factory.StartNew(() =>
{
var writer = new StreamWriter(writeStream);
writer.Write(callback + "(");
writer.Flush();
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait();
writer.Write(")");
writer.Flush();
});
}
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
private bool IsJsonpRequest(out string callback)
{
var query = HttpUtility.ParseQueryString(HttpRequest.RequestUri.Query);
callback = query[CallbackQueryParameter];
return !string.IsNullOrEmpty(callback);
}
}
这需要添加到您的启动中:
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
// Remove the XML formatter (only want JSON) see http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
config.Formatters.Remove(config.Formatters.XmlFormatter);
// add jsonp formatter as the one with the highest prio
config.Formatters.Insert(0, new JsonpMediaTypeFormatter());
// routes
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{arg1}/{arg2}",
defaults: new { arg1 = RouteParameter.Optional, arg2 = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
我认为,由于WebAPI的默认序列化程序是JSON.NET,因此需要将mediatypeformatter合并到一个子类中,JSON和jsonp才能工作(我使用的是WebapiContrib.Formatting.jsonp nuget包)。我在这里找到了一个解决方案,似乎可以做到这一点:我认为,由于WebAPI的默认序列化程序是JSON.NET,因此需要将mediatypeformatter合并到一个子类中,以便JSON和jsonp都能工作(我使用的是WebapiContrib.Formatting.jsonp nuget包)。我在这里找到了一个解决方案,似乎起到了作用: