如何将带有 ajax post 方法的复杂对象发送到 C# 控制器?
How do you send a complex object with an ajax post method to c# controller?
我正在尝试将复杂的 javascript 对象发送到 mvc 控制器 post 方法。
每次我 运行 该方法时,我都会收到 BadRequest 响应。它不允许我使用 visual studio 进行调试,只能使用 Web 开发人员工具进行调试。我检查了 fiddler 以查看我的 JSON 对象似乎与视图模型的顺序相同。有人可以帮我吗?
我正在使用 Asp.Net Core 1.0。如果我需要提供更多信息,请告诉我。
这是我的视图模型:
public class RouteViewModel
{
public RouteViewModel() { }
public List<CheckpointViewModel> Checkpoints { get; set; }
public int TotalDistance { get; set; }
}
public class CheckpointViewModel
{
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
}
编译对象的逻辑如下:
function createObject() {
var routeModel = { Checkpoints: [] ,TotalDistance:totalDistance};
for (var i = 0; i < markersOrders.length; i++) {
var latlng = markersOrders[i].getPosition();
var Checkpoint = {
'Latitude': latlng.lat(),
'Longitude': latlng.lng()
};
routeModel.Checkpoints.push(Checkpoint);
}
return JSON.stringify(routeModel);
}
这是我的 ajax 方法:
function saveRoute() {
var apiUrl = location.origin + "/map/AddRoute";
$.ajax({
method: "POST",
url: apiUrl,
contentType: "application/json;charset=utf-8",
data: (createObject())
}).done(function (msg) {
alert("Data saved: " + msg);
}).error(function(msg){alert("Error: "+ msg)});
}
接收post的控制器如下:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddRoute([FromBody]RouteViewModel route)
{
RouteViewModel newRoute = route;
if (ModelState.IsValid)
{
_context.AddRoute(newRoute.Checkpoints, newRoute.TotalDistance);
_context.SaveRoute();
return RedirectToAction("SavedRoutes");
}
else
{
return BadRequest(ModelState);
}
}
这是我的 RAW Post:
POST https://localhost:44343/map/AddRoute HTTP/1.1
Host: localhost:44343
Connection: keep-alive
Content-Length: 290
Accept: */*
Origin: https://localhost:44343
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: https://localhost:44343/Map/Map
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: .AspNetCore.Antiforgery.4IsE6XVGxQo=CfDJ8HmVr1mwBStLrOG_4RXM-sje_SmjZYd-GboPG5E19rchqlC61XsNEwa7yOgIySC-U63iTH6cD0ggwqwmwdPJOibPKrxlctls_a_b3wmPvai80vYUx6j0Lckfn24GBf7X_xZhAl3eac892j7YDJWa9Oc; .AspNetCore.Identity.Application=CfDJ8HmVr1mwBStLrOG_4RXM-shK66Uthf3kfJJezCs7HCTztr-seJHxVj8l5MS66u4EWd72NEXUjebAIfHIxFZvHjZzjiQSVfLCxdHnmcsbYWXgGAmaA_sBjdimNQXnPAC-NMtp_fDeTCPJEoB1lBy1hl-GFQaAJdRzVrcc7OchWTSBVZ9jdHmm0htNyChcJ8BUCczH8FhVnPeFzlCM_reR8u2vsQrOxY_ZmczdUQ_mqCmTVLGDdRRJwHLhuafrZ2mmAXq1iDzQhprtv98qAx2zM4TSoAOBKoeALq_Oa2n1SDvFMMtGseDB1mLsj-LkPlKhcCmtB14kwDRctvOtxOqCbQTfFjhLlc5405_dccQjWJ3mITtn1ss3x1aHUP-pHHzFX9ZhusQ1-IqV4pPDs12c1q2B5Uz0qEOHaUByVEE5bKpzklTT2kxNW1V81aGMMmwbi9zFkuh9nUFnQmGCqf5VXSx-FTm-UDWZgyMnK0JpG7K4cpiSeycv9sOeP1qUlz-P28RXLhCvqYAX3FIccRfoQMf63tU5OfVhu1bhRdV_NQALhBpku9nrxFyxxECe5WRc4It-kCLiaOQBlYa9bewb80QiWIS-wHNDY5vVcdAkd2D5
{"Checkpoints":[{"Latitude":-34.004057732693184,"Longitude":25.649633891880512},{"Latitude":-34.00313273259371,"Longitude":25.65392542630434},{"Latitude":-34.001425013635725,"Longitude":25.653367526829243},{"Latitude":-34.00019756942711,"Longitude":25.650320537388325}],"TotalDistance":919}
按照@Kiran Challa 的建议,我在控制器中收集了我的模型状态错误并将其写入输出 window,如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddRoute([FromBody]RouteViewModel route)
{
RouteViewModel newRoute = route;
if (ModelState.IsValid)
{
_context.AddRoute(newRoute.Checkpoints, newRoute.TotalDistance);
_context.SaveRoute();
return RedirectToAction("SavedRoutes");
}
else
{
//Getting errors
var errors = ModelState.Values.SelectMany(v => v.Errors);
Debug.WriteLine("Errors found: "+ errors+"\nEnd Errors found");
return BadRequest(ModelState);
}
}
在我的输出 window 中,当我触发控制器时,我收到的是:
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The required antiforgery header value "RequestVerificationToken" is not present.
at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.<ValidateRequestAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter.<OnAuthorizationAsync>d__3.MoveNext()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Warning: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter'.
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 400
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 37.4837ms 400
尝试让你的 createObject() return 这个:
function createObject() {
var routeModel = { Checkpoints: [] ,TotalDistance:totalDistance};
for (var i = 0; i < markersOrders.length; i++) {
var latlng = markersOrders[i].getPosition();
var Checkpoint = {
'Latitude': latlng.lat(),
'Longitude': latlng.lng()
};
routeModel.Checkpoints.push(Checkpoint);
}
return JSON.stringify({route: routeModel});
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddRoute(RouteViewModel route)
{
RouteViewModel newRoute = route;
if (ModelState.IsValid)
{
_context.AddRoute(newRoute.Checkpoints, newRoute.TotalDistance);
_context.SaveRoute();
return RedirectToAction("SavedRoutes");
}
else
{
return BadRequest(ModelState);
}
}
我发现我错在哪里了。我要么需要连同 ajax post 方法一起发送所需的验证令牌,要么在我的控制器中删除“[ValidateAntiForgeryToken]”。我选择了后者,因为安全不是我目前的 objective。感谢建议@KiranChalla –
我正在尝试将复杂的 javascript 对象发送到 mvc 控制器 post 方法。 每次我 运行 该方法时,我都会收到 BadRequest 响应。它不允许我使用 visual studio 进行调试,只能使用 Web 开发人员工具进行调试。我检查了 fiddler 以查看我的 JSON 对象似乎与视图模型的顺序相同。有人可以帮我吗? 我正在使用 Asp.Net Core 1.0。如果我需要提供更多信息,请告诉我。
这是我的视图模型:
public class RouteViewModel
{
public RouteViewModel() { }
public List<CheckpointViewModel> Checkpoints { get; set; }
public int TotalDistance { get; set; }
}
public class CheckpointViewModel
{
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
}
编译对象的逻辑如下:
function createObject() {
var routeModel = { Checkpoints: [] ,TotalDistance:totalDistance};
for (var i = 0; i < markersOrders.length; i++) {
var latlng = markersOrders[i].getPosition();
var Checkpoint = {
'Latitude': latlng.lat(),
'Longitude': latlng.lng()
};
routeModel.Checkpoints.push(Checkpoint);
}
return JSON.stringify(routeModel);
}
这是我的 ajax 方法:
function saveRoute() {
var apiUrl = location.origin + "/map/AddRoute";
$.ajax({
method: "POST",
url: apiUrl,
contentType: "application/json;charset=utf-8",
data: (createObject())
}).done(function (msg) {
alert("Data saved: " + msg);
}).error(function(msg){alert("Error: "+ msg)});
}
接收post的控制器如下:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddRoute([FromBody]RouteViewModel route)
{
RouteViewModel newRoute = route;
if (ModelState.IsValid)
{
_context.AddRoute(newRoute.Checkpoints, newRoute.TotalDistance);
_context.SaveRoute();
return RedirectToAction("SavedRoutes");
}
else
{
return BadRequest(ModelState);
}
}
这是我的 RAW Post:
POST https://localhost:44343/map/AddRoute HTTP/1.1
Host: localhost:44343
Connection: keep-alive
Content-Length: 290
Accept: */*
Origin: https://localhost:44343
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: https://localhost:44343/Map/Map
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: .AspNetCore.Antiforgery.4IsE6XVGxQo=CfDJ8HmVr1mwBStLrOG_4RXM-sje_SmjZYd-GboPG5E19rchqlC61XsNEwa7yOgIySC-U63iTH6cD0ggwqwmwdPJOibPKrxlctls_a_b3wmPvai80vYUx6j0Lckfn24GBf7X_xZhAl3eac892j7YDJWa9Oc; .AspNetCore.Identity.Application=CfDJ8HmVr1mwBStLrOG_4RXM-shK66Uthf3kfJJezCs7HCTztr-seJHxVj8l5MS66u4EWd72NEXUjebAIfHIxFZvHjZzjiQSVfLCxdHnmcsbYWXgGAmaA_sBjdimNQXnPAC-NMtp_fDeTCPJEoB1lBy1hl-GFQaAJdRzVrcc7OchWTSBVZ9jdHmm0htNyChcJ8BUCczH8FhVnPeFzlCM_reR8u2vsQrOxY_ZmczdUQ_mqCmTVLGDdRRJwHLhuafrZ2mmAXq1iDzQhprtv98qAx2zM4TSoAOBKoeALq_Oa2n1SDvFMMtGseDB1mLsj-LkPlKhcCmtB14kwDRctvOtxOqCbQTfFjhLlc5405_dccQjWJ3mITtn1ss3x1aHUP-pHHzFX9ZhusQ1-IqV4pPDs12c1q2B5Uz0qEOHaUByVEE5bKpzklTT2kxNW1V81aGMMmwbi9zFkuh9nUFnQmGCqf5VXSx-FTm-UDWZgyMnK0JpG7K4cpiSeycv9sOeP1qUlz-P28RXLhCvqYAX3FIccRfoQMf63tU5OfVhu1bhRdV_NQALhBpku9nrxFyxxECe5WRc4It-kCLiaOQBlYa9bewb80QiWIS-wHNDY5vVcdAkd2D5
{"Checkpoints":[{"Latitude":-34.004057732693184,"Longitude":25.649633891880512},{"Latitude":-34.00313273259371,"Longitude":25.65392542630434},{"Latitude":-34.001425013635725,"Longitude":25.653367526829243},{"Latitude":-34.00019756942711,"Longitude":25.650320537388325}],"TotalDistance":919}
按照@Kiran Challa 的建议,我在控制器中收集了我的模型状态错误并将其写入输出 window,如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddRoute([FromBody]RouteViewModel route)
{
RouteViewModel newRoute = route;
if (ModelState.IsValid)
{
_context.AddRoute(newRoute.Checkpoints, newRoute.TotalDistance);
_context.SaveRoute();
return RedirectToAction("SavedRoutes");
}
else
{
//Getting errors
var errors = ModelState.Values.SelectMany(v => v.Errors);
Debug.WriteLine("Errors found: "+ errors+"\nEnd Errors found");
return BadRequest(ModelState);
}
}
在我的输出 window 中,当我触发控制器时,我收到的是:
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The required antiforgery header value "RequestVerificationToken" is not present.
at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.<ValidateRequestAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter.<OnAuthorizationAsync>d__3.MoveNext()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Warning: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter'.
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 400
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 37.4837ms 400
尝试让你的 createObject() return 这个:
function createObject() {
var routeModel = { Checkpoints: [] ,TotalDistance:totalDistance};
for (var i = 0; i < markersOrders.length; i++) {
var latlng = markersOrders[i].getPosition();
var Checkpoint = {
'Latitude': latlng.lat(),
'Longitude': latlng.lng()
};
routeModel.Checkpoints.push(Checkpoint);
}
return JSON.stringify({route: routeModel});
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddRoute(RouteViewModel route)
{
RouteViewModel newRoute = route;
if (ModelState.IsValid)
{
_context.AddRoute(newRoute.Checkpoints, newRoute.TotalDistance);
_context.SaveRoute();
return RedirectToAction("SavedRoutes");
}
else
{
return BadRequest(ModelState);
}
}
我发现我错在哪里了。我要么需要连同 ajax post 方法一起发送所需的验证令牌,要么在我的控制器中删除“[ValidateAntiForgeryToken]”。我选择了后者,因为安全不是我目前的 objective。感谢建议@KiranChalla –