Cors, Web Api, IE8, Post Complex Data
Как часть моей рабочей среды мы должны поддерживать IE8, но хотели бы двигаться вперед с технологиями, в частности, с CORS.I '
Я не могу отправить сложные объекты в службу Cors в ie8. Объект является нулевым. Ниже приведены шаги для воспроизведения. При необходимости я могу загрузить проект на github.I '
Мы создали новый проект MVC4. Добавлен API-контроллер. И внесли следующие изменения.
Для поддержки предполетных сложных вызовов cors (global.asax): protected void Application_BeginRequest()
{
//This is needed for the preflight message
//https://stackoverflow.com/questions/13624386/handling-cors-preflight-requests-to-asp-net-mvc-actions
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") { Response.Flush(); }
}
Источник:Обработка запросов CORS Preflight к действиям ASP.NET MVC
Поддержать text / plain (т.е. 8 отправляет только text / plain с cors) (global.asax): protected void Application_Start()
{
//This is needed to support text/plain
HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
config.Formatters.Remove(config.Formatters.FormUrlEncodedFormatter);
config.Formatters.Remove(config.Formatters.XmlFormatter);
...
}
Кредит:Публикация текста / обычного как сложного объекта в WebAPI с помощью CORS
Поддержка дополнительных имен функций, отличных от глаголов (put / post / etc) (WebApiConfig.cs) " public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "APICustom",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
...
}
Поддерживать cors (web.config)
Контроллер API, я назвал PersonController.cs public class PersonController : ApiController
{
public List Get()
{
List s = new List();
s.Add("s");
s.Add("t");
s.Add("u");
return s;
}
[Serializable()]
public class BaseReply
{
public bool successful = true;
public string error;
}
[Serializable()]
public class UpdateSomethingReply: BaseReply
{
public UpdateSomethingRequest request;
public List stuff = new List();
}
[Serializable()]
public class UpdateSomethingRequest
{
public int hasInt;
public string hasString;
}
//[FromBody]
[HttpPost]
public UpdateSomethingReply UpdateSomething([FromBody] UpdateSomethingRequest request)
{
string body = Request.Content.ReadAsStringAsync().Result;
UpdateSomethingReply reply = new UpdateSomethingReply();
reply.request = request;
reply.stuff.Add("v");
reply.stuff.Add("w");
reply.stuff.Add("x");
return reply;
}
Это степень изменений в услуге. Итак, затем я создаю клиента. Это также проект MVC4. Довольно простые вещи здесь.
Чтобы заполнить ie8 с помощью cors (index.cshtml):
Источник:https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
Чтобы позвонить в службу Cors $(document).ready(function () {
$.when(
$.ajax({
url: urls.person.UpdateSomething,
type: 'post',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({
hasInt: 1,
hasString: "u"
})
})
)
.fail(function (jqXHR, textStatus, errorThrown) {
})
.done(function (data) {
console.log(JSON.stringify(data));
});
$.when(
$.ajax({
url: urls.person.Get,
dataType: 'json'
})
)
.fail(function (jqXHR, textStatus, errorThrown) {
})
.done(function (data) {
console.log(JSON.stringify(data));
});
$.when(
$.ajax({
url: urls.person.UpdateSomething,
type: 'post',
contentType: "text/plain",
dataType: 'json',
data: JSON.stringify({
hasInt: 1,
hasString: "u"
})
})
)
.fail(function (jqXHR, textStatus, errorThrown) {
})
.done(function (data) {
console.log(JSON.stringify(data));
});
});
Как я уже говорил ранее, все 3 звонка завершены в ie8. Но объект запроса в сервисе является нулевым в ie8, а в firefox он заполняется, даже когда я вынуждаю тип содержимого text / plain
Выход консоли IE8:
{"request":null,"stuff":["v","w","x"],"successful":true,"error":null}
Выход консоли Firefox:
{"request":{"hasInt":1,"hasString":"u"},"stuff":["v","w","x"],"successful":true,"error":null}
Обновление 25.09.2013Я могу подтвердить, что тело отправляется, но неt анализируется веб-интерфейсом API. Если я добавлю следующий хак, он вернет данные, как и ожидалось. В Firefox тело будет пустым, а объект запроса будет заполнен. В ie8 тело все еще содержит содержимое, и запрос является нулевым.
[HttpPost]
public UpdateSomethingReply UpdateSomething(UpdateSomethingRequest request)
{
if (request == null && Request.Content.ReadAsStringAsync().Result !="")
{
request = JsonConvert.DeserializeObject(Request.Content.ReadAsStringAsync().Result);
}
UpdateSomethingReply reply = new UpdateSomethingReply();
reply.request = request;
reply.body=Request.Content.ReadAsStringAsync().Result;
reply.headers = Request.Headers.ToString();
reply.stuff.Add("v");
reply.stuff.Add("w");
reply.stuff.Add("x");
return reply;
}