Проблема с привязкой к модели с ASP.NET5 MVC6
Я пытаюсь опубликовать некоторые данные JSON в форме angular для моего действия MVC6-контроллера ASP.NET5. Модельное связующее, похоже, не работает. Не уверен, что мне здесь не хватает.
Мой ASP-контроллер:
public class DefaultController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult SubmitTest(QTestViewModel model)
{
return Json("true");
}
}
My angular Контроллер:
angular.module("testActiveMq", [])
.controller("MqTestController", ["$scope", "$http", function ($scope, $http) {
// Submit Form
$scope.submitForm = function () {
debugger;
var formData = (this.data) ? angular.toJson(this.data) : null;
if (formData && this.qForm && this.qForm.$valid) {
$http({
url: "/Default/SubmitTest",
data: formData,
method: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8"
})
.then(function successCallback(response) {
debugger;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
debugger;
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
};
}])
Моя модель просмотра:
public class QTestViewModel
{
public string MqBrokerUri { get; set; }
public string ClientId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int TotalRequests { get; set; }
public int MaxConcurrentRequests { get; set; }
public int DelayBetweenThreads { get; set; }
}
Когда я делаю запрос, заголовки HTTP...
POST /Default/SubmitTest HTTP/1.1
Host: localhost:50877
Connection: keep-alive
Content-Length: 225
Accept: application/json, text/plain, */*
Origin: http://localhost:50877
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:50877/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Мои данные формы выглядят так.
{"MqBrokerUri":"ssl://broker-uri:1616?transport.acceptInvalidBrokerCert=true","ClientId":"MqLoadTest","UserName":"myunm","Password":"mypwd","TotalRequests":100,"MaxConcurrentRequests":10,"DelayBetweenThreads":1}
Я чувствую, что мне не хватает чего-то сверх очевидного. Почему данные JSON не привязаны к моей модели? Наверняка мне не нужен специальный связующий элемент для чего-то такого простого?
Ответы
Ответ 1
Ваш код был достаточно в MVC 5 и более ранних версиях для получения модели в вашем контроллере.
Однако в MVC 6 вам также необходимо установить параметр [FromBody]
в действие вашего контроллера:
[HttpPost]
public IActionResult SubmitTest([FromBody]QTestViewModel model)
{
return Json("true");
}
Не уверен, почему это требование в MVC 6, но ваша модель сохранит свои значения по умолчанию, если вы не добавите атрибут FromBody.
-
Проверьте, например, руководство по веб-API в официальных документах.
-
После некоторого копания в источнике кажется, что BodyModelBinder
будет принимать только модели, которые специально активировали привязку body который добавлен атрибут [FromBody]
.
var allowedBindingSource = bindingContext.BindingSource;
if (allowedBindingSource == null ||
!allowedBindingSource.CanAcceptDataFrom(BindingSource.Body))
{
// Formatters are opt-in. This model either didn't specify [FromBody] or specified something
// incompatible so let other binders run.
return ModelBindingResult.NoResultAsync;
}
PS. Angular строит по умолчанию объекты json, но если вы используете что-то вроде jQuery, вам также нужно вручную вызвать JSON.stringify
.
Ответ 2
Когда-нибудь это случилось с json, чтобы использовать его
var jsonResult=json("true");
jsonResult.maxJsonLength=int32.maxValue
return jsonresult;
Надеюсь, это поможет вам.
Ответ 3
[edit] Похоже, этот ответ неверен. Моя проблема была вызвана тем, что параметр Action назван таким же, как одно из свойств объекта. Это привело к тому, что MVC использовал префикс для предотвращения неоднозначности. Я не согласен с тем, что это неоднозначно, и я обсуждаю это на Github.
Я только что зарегистрировал ошибку в Github об этом. Кажется, что если ваш параметр не назван CamelCase типа параметра, он ожидает, что поля в полезной нагрузке будут иметь префикс имени параметра.
Вы можете исправить это, добавив [Bind (Prefix = "")] перед параметром Action.
public IActionResult SubmitTest([Bind(Prefix="")]QTestViewModel model)
Ответ 4
Ok @Daniel J.G. ответ не работал у меня
Мне пришлось использовать
[FromForm] вместо [FromBody] Чтобы заставить работать binging
[HttpPost]
public IActionResult SubmitTest([FromForm]QTestViewModel model)
{
return Json("true");
}