Почему мой вызов ajax / fetch не работает без маршрута в моем контроллере? - PullRequest
0 голосов
/ 25 ноября 2018

Я потратил уже много часов на проблему, и я не могу понять, почему мой пост 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"
                    });

Routungот 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")] в моемконтроллер и url: "/comments/new/AddComment", в моем Ajax.

Мне нужно использовать [HttpPost], чтобы контроллер мог использовать [ValidateAntiForgeryToken], я так думаю.Но в любом случае мой Ajax и Controller соответствуют большинству популярных примеров поста Ajax, которые я мог найти здесь, и я понятия не имею, почему он не работает.

EDIT:

Я пытался добиться того же с вызовом 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" звонка нет вообще.

ОБНОВЛЕНИЕ

После очистки всех данных браузера и использования: controller:

[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);
                        });

Я все еще получаю журнал XHR для URL звонка: http://localhost:58256/comments/new?Name=aa&Change=aaa&Opinion=good Почему?

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Клиентская сторона говорит, что отправляет 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"
    });

Наконец, сообщите действию Server, что нужно ожидать данные в теле запроса, используя [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();
}
0 голосов
/ 26 ноября 2018

Строка

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

означает, что путь /Survey/AddComment будет вызывать действие

SurveyController.AddComment ()

Идентификаторотмечен знаком "?"является необязательным ({id?}).

Если вы хотите определить маршрут в контроллере, вы можете сделать что-то вроде следующего.

[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");
    }
}

В обоих случаях вы должны отметитьДействие с [HttpPost], если вы отправляете запрос POST.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...