【问题标题】:Model Binding Issue with ASP.NET5 MVC6ASP.NET 5 MVC 6 的模型绑定问题
【发布时间】:2016-03-08 22:34:27
【问题描述】:

我正在尝试将一些 JSON 数据以角度形式发布到我的 ASP.NET5 MVC6 控制器操作中。模型活页夹似乎不起作用。不知道我在这里缺少什么。

我的 ASP 控制器:

public class DefaultController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public IActionResult SubmitTest(QTestViewModel model)
    {
        return Json("true");
    }
}

我的 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 数据没有绑定到我的模型?这么简单的事情我肯定不需要自定义模型绑定器吗?

【问题讨论】:

  • 尝试将 public IActionResult SubmitTest(QTestViewModel model) 更改为 public IActionResult SubmitTest(string model) 作为快速测试,看看它会返回什么
  • 也可以试试public IActionResult SubmitTest([FromBody] QTestViewModel model)
  • 你错过了JsonRequestBehavior.AllowGet。改为return Json("true", JsonRequestBehavior.AllowGet);

标签: c# asp.net angularjs json asp.net-core-mvc


【解决方案1】:

好的@Daniel J.G.回答对我不起作用 我不得不使用 [FromForm] 而不是 [FromBody] 让 binging 正常工作

  [HttpPost]
public IActionResult SubmitTest([FromForm]QTestViewModel model)
{
    return Json("true");
}

【讨论】:

    【解决方案2】:

    [编辑] 看来这个答案是不正确的。我的问题是由于 Action 参数被命名为与对象的属性之一相同。这导致 MVC 使用前缀来防止歧义。我不同意这是模棱两可的,我正在Github 上讨论这个问题。


    我刚刚在 Github 上记录了一个关于此的错误。看来,如果您的参数未命名为参数类型的 CamelCase,则它希望有效负载中的字段以参数名称为前缀。

    您可以通过在 Action 的参数前添加 [Bind(Prefix="")] 来解决此问题。 public IActionResult SubmitTest([Bind(Prefix="")]QTestViewModel model)

    【讨论】:

      【解决方案3】:

      有时会发生 json 更好地使用它

      var jsonResult=json("true");
      jsonResult.maxJsonLength=int32.maxValue
      return jsonresult;
      

      希望对你有帮助。

      【讨论】:

        【解决方案4】:

        您的代码在 MVC 5 及更早版本中足以在您的控制器中接收模型。 但是在 MVC 6 中,您还需要在控制器操作中设置 [FromBody] 参数:

        [HttpPost]
        public IActionResult SubmitTest([FromBody]QTestViewModel model)
        {
            return Json("true");
        }
        

        不确定为什么这是 MVC 6 中的要求,但如果您不添加 FromBody 属性,您的模型将保留其默认值。

        • 例如查看官方文档中的Web API tutorial

        • 在深入挖掘源代码后,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

        【讨论】:

        • 这不起作用。视图模型中的所有值在到达控制器时都为空。
        猜你喜欢
        • 1970-01-01
        • 2016-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-27
        • 1970-01-01
        • 2023-03-07
        相关资源
        最近更新 更多