Не проходит POST-запрос в C# asp net mvc
Есть модель данных:
public class AccrualPayment
{
public string OIDobject { get; set; }
public string PersonalAccount { get; set; }
public string IdAccrual { get; set; }
public string DateAccrual { get; set; }
public string SummAccrual { get; set; }
public string DatePayment { get; set; }
public string SummPayment { get; set; }
public AccrualPayment(string oidObject, string personalAccount, string idAccrual, string dateAccrual, string summAccrual, string datePayment, string summPayment)
{
OIDobject = oidObject;
PersonalAccount = personalAccount;
IdAccrual = idAccrual;
DateAccrual = dateAccrual;
SummAccrual = summAccrual;
DatePayment = datePayment;
SummPayment = summPayment;
}
}
Есть контроллер принимающий POST-запрос с параметром - объект модели данных:
public class FileApiController : ApiController
{
[HttpPost]
[Route("api/FileApi/uploadData")]
public void UploadData([FromBody] AccrualPayment [] accrualPayment)
{
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
...
}
}
На странице фронта ajax запрос отправляющий массив json на сервер в теле запроса:
$(".uploadData").click(async function () {
var data = await ExcelToJSON('AccrualsPaymentsSocialRent');
if (data != undefined & data.length > 0){
data = data[0];
}
$.ajax({
type: "POST",
url: "http://localhost:6141/api/FileApi/uploadData",
contentType: "application/json;charset=utf-8",
processData: false,
data: JSON.stringify(data),
success: function (response) {
alert(response);
console.log(response);
},
error: function (result, status, er) {
alert("error: " + result + " status: " + status + " er:" + er);
}
});
});
Запрос почему-то не проходит - при отладке до тчк остановы в контроллере не доходит, а среда разработки выдает сообщение:
В потоке не запущен совместимый код
Выбранный модуль отладки не поддерживает выполнение любого кода в текущем потоке (например, выполняется только машинный код среды выполнения). Вы можете переключиться на другой поток, чтобы проверить, выполняется ли совместимый код.
Содержимое отправляемого json-массива:
data: Array(3)
0: {OIDobject: "aaa13548", PersonalAccount: "00000000001", "IdAccrual ": "00aa00bb01", DateAccrual: "2021.05.21", SummAccrual: "3333", …}
1: {OIDobject: "bbb5433", PersonalAccount: "00000000002", "IdAccrual ": "00aa00bb02", DateAccrual: "2021.05.21", SummAccrual: "2222", …}
2: {OIDobject: "ccc02143", PersonalAccount: "00000000003", "IdAccrual ": "00aa00bb03", DateAccrual: "2021.05.21", SummAccrual: "4444", …}
length: 3
{
"OIDobject": "aaa13548",
"PersonalAccount": "00000000001",
"IdAccrual ": "00aa00bb01",
"DateAccrual": "2021.05.21",
"SummAccrual": "3333",
"DatePayment": "2021.05.21",
"SummPayment": "1111"
}
Сервис на Framework 4.5
Global.asax.cs:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Файл Web.config:
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<!--
Описание изменений web.config см. по адресу http://go.microsoft.com/fwlink/?LinkId=235367.
Следующие атрибуты можно установить с помощью тега <httpRuntime>.
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime />
<pages controlRenderingCompatibilityVersion="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Попытался переименовать поля в JSON, чтобы они начинались с символа нижнего регистра - выдало ошибку:
Access to XMLHttpRequest at 'http://localhost:6141/api/FileApi/uploadData' from origin 'https://localhost:44367' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Ведать запрос проходит уже доходит до сервера, но сервер его блокирует, хотя у меня в контроллере указано:
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
Ответы (1 шт):
Судя по ошибке, у вас для Web Api сервера не настроен CORS. То, что вы написали в контроллере:
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
должен делать Middleware до попадания в метод обработки запроса. CORS в ASP.NET Web Api реализован и доступен "из-под капота".
Чтобы включить CORS, вам нужно установить nuget-пакет Microsoft.AspNet.WebApi.Cors и в метод WebApiConfig.Register добавить EnableCors. Есть два немного разных способа добавления CORS:
- Добавить CORS для всех api-контроллеров;
- Добавить CORS для нужного контроллера/метода.
Способ №1
Требует лишь одного изменения в WebApiConfig.Register:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*")
{
SupportsCredentials = true // По дефолту, false. Если cross-origin запрос должен отправлять еще и данные для аутентификации (например, Cookie), то нужно выставить это поле в true
};
config.EnableCors(cors);
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
По сути, этот способ добавляет к каждому api-контроллеру и api-методу CORS policy (действует так же, будто бы мы написали для каждого api-контроллера атрибут [EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)])
Способ №2
В WebApiConfig.Register:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
И в FileApiController.cs
public class FileApiController : ApiController
{
[HttpPost]
[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]
[Route("api/FileApi/uploadData")]
public void UploadData([FromBody] AccrualPayment [] accrualPayment)
{
//...
}
}
Подробнее про EnableCors можно почитать в документации Microsoft: https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api