为什么我的ajax / fetch调用在控制器中没有Route的情况下不起作用?

时间:2018-11-25 20:33:15

标签: c# ajax asp.net-core-mvc

我已经在这个问题上花费了很长时间,而且我不明白为什么我的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 为什么?

2 个答案:

答案 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]标记操作。