我已经在这个问题上花费了很长时间,而且我不明白为什么我的jquery ajax帖子不能与SurveyController.cs
一起使用:
[HttpPost]
public ActionResult AddComment(Survey survey)
{
if (survey == null)
{
return NotFound();
}
if (survey != null)
{
survey.Time = DateTime.Now;
_context.Surveys.Add(survey);
_context.SaveChanges();
}
return null;
}
Ajax:
const queryParams = `Name=${this.state.surveyState.name}&Change=${this.state.surveyState.change}&Opinion=${this.state.surveyState.opinion}`;
$.ajax({
type: 'POST',
url: "/Survey/AddComment",
data: queryParams,
contentType: "application/json; charset=utf-8",
dataType: "html"
});
来自Startup.cs
的Routung:
app.UseMvc(routes => {
routes.MapRoute(name: "Error", template: "Error",
defaults: new { controller = "Error", action = "Error" });
routes.MapRoute(
name: "default", template: "{controller}/{action}/{id?}",
defaults: new { controller = "MyProjects", action = "Index" });
});
它不会给我控制台带来任何错误,但不会在控制器中遇到任何断点。
仅当我在控制器中使用[Route("comments/new")]
并在Ajax中使用url: "/comments/new/AddComment",
时,此方法才有效。
我认为,控制器需要使用[HttpPost]
才能使用[ValidateAntiForgeryToken]
。但是无论如何,根据我在这里可以找到的大多数Ajax帖子的流行示例,我的Ajax和Controller都是这样,而且我不知道为什么它确实不起作用。
编辑:
我尝试通过Fetch调用实现相同的效果:
const queryParams = `Name=${this.state.surveyState.name}&Change=${this.state.surveyState.change}&Opinion=${this.state.surveyState.opinion}`;
fetch(`/comments/new?`,
{
method: 'POST',
body: JSON.stringify({ queryParams }), // data can be `string` or {object}!
headers: { 'Content-Type': 'application/json' },
credentials: 'include'
}
)
.then(res => res.json())
.then(res => {
console.log(res);
})
.catch(error => {
console.error(error);
});
具有相同的结果。
我注意到,在控制台日志的XHR
中,呼叫类型是GET
而不是POST
,与AJAX
呼叫相同。为什么?
更新:
由于某些原因,在进行更改时
fetch(/comments/new?
至
fetch(/Survey/AddComment
XHR给了我相同的通话URL:
http://localhost:58256/comments/new?Name=aaa&Change=aaa&Opinion=good
无论我在那儿等什么,它都不会改变!!(?)。
更新:
删除[Route("comments/new")]
并离开fetch("/Survey/AddComment"
之后,根本没有通话。
更新
清除整个浏览器的数据,并使用: 控制器:
[HttpPost]
public IActionResult AddComment([FromBody]Survey survey)
{
if (survey == null)
{
return BadRequest();
}
survey.Time = DateTime.Now;
_context.Surveys.Add(survey);
_context.SaveChanges();
return Ok();
}
获取:
const data = {
Name: this.state.surveyState.name,
Change: this.state.surveyState.change,
Opinion: this.state.surveyState.opinion
};
fetch("/Survey/AddComment",
{
method: 'POST',
body: JSON.stringify({ data}), // data can be `string` or {object}!
headers: { 'Content-Type': 'application/json' },
credentials: 'include'
}
)
.then(res => res.json())
.then(res => {
console.log(res);
})
.catch(error => {
console.error(error);
});
我仍在获取有关呼叫URL的XHR日志:
http://localhost:58256/comments/new?Name=aa&Change=aaa&Opinion=good
为什么?
答案 0 :(得分:3)
客户端说它正在发送application/json
,但是
const queryParams = `Name=${this.state.surveyState.name}&Change=${this.state.surveyState.change}&Opinion=${this.state.surveyState.opinion}`;
不是JSON。看起来更像是您要在查询字符串中发送的数据。
构造有效的JSON有效负载
const data = {
Name: ${this.state.surveyState.name},
Change: ${this.state.surveyState.change},
Opinion: ${this.state.surveyState.opinion}
};
并将其以正确的格式发送到服务器
$.ajax({
type: 'POST',
url: "/Survey/AddComment",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
最后,通过使用[FromBody]
[HttpPost]
public IActionResult AddComment([FromBody]Survey survey) {
if (survey == null) {
return BadRequest();
}
survey.Time = DateTime.Now;
_context.Surveys.Add(survey);
_context.SaveChanges();
return Ok();
}
答案 1 :(得分:0)
行
name: "default", template: "{controller}/{action}/{id?}",
表示路径/Survey/AddComment
将调用操作
SurveyController.AddComment()
标有“?”的ID是可选的({id?})。
如果要在Controller中定义路由,可以执行以下操作。
[Route("[controller]/[action]")]
public class SurveyController : Controller {
[HttpPost]
public ActionResult AddComment(Survey survey)
{
survey.Time = DateTime.Now;
_context.Surveys.Add(survey);
_context.SaveChanges();
return Content("Added");
}
}
在两种情况下,如果您发送POST请求,都必须用[HttpPost]标记操作。