【问题标题】:Why my ajax/fetch call does not work with no Route in my controller?为什么我的 ajax/fetch 调用在我的控制器中没有路由时不起作用?
【发布时间】:2018-11-25 20:33:14
【问题描述】:

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

阿贾克斯:

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的路由:

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 帖子示例,我不知道为什么它不起作用。

编辑:

我尝试通过 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 为什么?

【问题讨论】:

  • 如果您添加类属性、控制器的类名 (SurveyController???]、操作 AddComment() 的属性以及您的 Startup.cs 的路由定义可能会有所帮助例子。当然,如果你想处理一个 POST,你必须使用属性 HttpPost。
  • @koalabruder 已更新
  • 我再次尝试使用 fetch 调用,结果相同(请参阅已编辑的问题)。我注意到,在XHR 控制台日志中,调用类型是GET,而不是POST,也适用于ajax 调用。我不明白为什么?

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


【解决方案1】:

客户端说它正在发送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();
}

【讨论】:

  • 我确实像你发布的那样,没有任何东西击中 public IActionResult AddComment([FromBody]Survey survey) 内部的断点
  • 我再次尝试使用 fetch 调用,结果相同(请参阅编辑后的问题)。我注意到,在XHR 控制台日志中,调用类型是GET,而不是POST,也适用于ajax 调用。我不明白为什么?
  • @Przemyslaw.Pszemek 在您的更新中,您似乎仍然错误地发送了数据。仔细查看我的回答,注意我是如何构建要发送的数据的。
  • @我尝试了您的方法,请参阅有关该问题的最新 UPDATE。由于某种原因,即使将 Fetch URL 更改为:/Survey/AddComment,我也会进入 XHR 记录旧 URL:http://localhost:58256/comments/new?Name=aa&Change=aaa&Opinion=good。我也有相同的结果,使用格式:${this.state.surveyState.name} 作为属性。
  • P.S.你认为 React 应用调用 Fetch 是否重要?
【解决方案2】:

线

name: "default", template: "{controller}/{action}/{id?}",

表示路径/Survey/AddComment会调用Action

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

【讨论】:

  • 我确实喜欢你的提议,但由于某种原因,它没有通过行动
猜你喜欢
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2021-08-02
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多