当前位置: 首页 > 知识库问答 >
问题:

在. NET核心中发布多个带有Ajax的模型对象

邢高爽
2023-03-14

我一直在绞尽脑汁,以及关于同一主题的各种SO帖子(请参阅JQuery Ajax和将多个复杂对象发布到asp.net MVC控制器、将多个对象传递到我的控制器等),但我很难从Ajax调用中将多个对象发布到我的控制器(.net Core)。我相信我已经像本教程一样设置了我的代码(http://www.dotnetcurry.com/aspnet-mvc/1253/multiple-model-objects-input-controller-action-methods)并使用了以下建议:http://andrewlock.net/model-binding-json-posts-in-asp-net-core/无济于事。

问题:我只能获得第一个对象,但不能获得第二个对象进行绑定。

控制器方法:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Apply(ApplicationInfoViewModel info, SRAgreementViewModel agreement)
{
     if(ModelState.IsValid){
     //do stuff. ModelState.IsValid returns false here.
     }
}

这是我的JS:

$(function () {
    $("#ApplyBAOForm").submit(function (e) {        
        var jsonObj = $('#ApplyForm').serialize();
        var srFormJsonObj = $('#SRForm').serialize();

        $.ajax({
            url: "ApplyBao/Apply",
            datatype: "json",
            contentType: "application/json; charset=utf-8",
            data: { info: jsonObj, agreement: srFormJsonObj },
            type: "POST"
        }).done(function (result) {
            console.log("Apply success: " + result);
            if (result.type === "success") {
                 //hooray  
            }
            else {
                //boo                
            }
        });

    });
});

所以这是一个有点奇怪的情况:实际上这里有来自两种不同形式的数据。SRform数据在提交ApplyForm之前进行验证(它处于模式中),但实际上只提交给ApplyForm进行持久化。从这两个表单得到的序列化对象似乎是正确的和相似的(jsonObj和srFormObj)。

当我到达ModelState时。IsValid语句,它返回false,因为SRAgreement对象本质上为null(使用默认值)。但是,ApplicationInfoViewModel对象正确显示表单中的数据。

我尝试过的其他事情:

  • 将两个对象组合到一个视图模型中(两个子对象最终都为空?)
  • 将SR协议对象添加为Application ationInfo对象的子对象;SR协议对象为空。
  • 添加Andrew Lock的博客文章所描述的[FromBody],此jsut导致HTTP 415不支持的媒体类型响应

可能有更好的方法可以做到这一点,但我认为我正在尝试的应该是可行的。

谢啦!

编辑2:

看起来我甚至不能绑定一个JSON对象。我一定错过了一些简单的事情。我将其简化为仅将两个对象中的一个作为JSON提交:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Apply([FromBody] ApplicationInfoViewModel info) 
{
    if (ModelState.IsValid)
    {
     // do stuff
    }
 }

JS公司:

$("#ApplyBAOForm").submit(function (e) {
        e.preventDefault();

        var jsonObj = ConvertFormToJSON($("#ApplyBAOForm"));
        var srFormJsonObj = ConvertFormToJSON($("#SRForm"));
        var obj2 = JSON.stringify({ info: jsonObj });

        $.ajax({
            url: "ApplyBao/Apply",
            datatype: "json",
            contentType: "application/json; charset=utf-8",
            data: obj2,
            //data: JSON.stringify(jsonObj),
            type: "POST"
        }).done(function (result) {
            console.log("Apply success: " + result);

            }
            else {
                //show some error message or something                
            }
        });        
    });
});

现在请求如下所示:

Request URL:http://localhost:19194/ApplyBao/Apply
Request Method:POST
Status Code:400 Bad Request
Remote Address:[::1]:19194
Response Headers
view parsed
HTTP/1.1 400 Bad Request
Server: Kestrel
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNccmdiMDA3M1xEb2N1bWVudHNcYmFvYWRtaW5pc3RyYXRpb25cc3JjXEJBT0FkbWluaXN0cmF0aW9uXEFwcGx5QmFvXEFwcGx5?=
X-Powered-By: ASP.NET
Date: Thu, 12 Jan 2017 21:59:27 GMT
Content-Length: 0
Request Headers
view parsed
POST /ApplyBao/Apply HTTP/1.1
Host: localhost:19194
Connection: keep-alive
Content-Length: 580
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Origin: http://localhost:19194
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: application/json; charset=UTF-8
Referer: http://localhost:19194/ApplyBao
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: .AspNetCore.Antiforgery.l7Q8WGuEtq8=CfDJ8K9L5D4kNnBPrb3_9Hu-w57rjjf751Qf9eh-z57qWmtMA53AB6FXsZ7pbIuLkdP2F6GjA7TGl0Tz7TfACCn3QeFt_uC-BgsYnk3Nd8z0ZA0c90XVEA90NnQOnmVFRu_KF2_2DXV89Jur84rMa-s26nQ
Request Payload
view parsed
{"info":{"HearAboutUsSelectedId":"137","FirstName":"Ron","LastName":"Bud","MiddleName":"","MaidenName":"","Email":"r@test.com","BirthDate":"1900-01-15","Phone":"123456","Fax":"","Street":"1234","City":"Denton","State":"TX","Zip":"12345","Country":"USA","SelectedExamTrack":"BCaBA","SelectedTranscriptSendMethod":"requested","Degree":"Education","SraId":"00000000-0000-0000-0000-000000000000","__RequestVerificationToken":"CfDJ8K9L5D4kNnBPrb3_9Hu-w56wPCITEDVZQo7flUIB70Pu4Q81TlRXa_oI4t8Bleou6l45oHHmUFrKusKofA6Gey-uSgKP7M3L-DrawE1TVJnrDsULHlnOE9ngg9LuyFK6-cylBJ-91h5fmaico-0yrZE"}}

JSON现在看起来像一个合适的JSON对象,但我的公主似乎在另一个城堡里。我是否还缺少其他东西来启用它?

更新:

我终于明白了。事实证明,AntiForgery令牌导致请求失败,如这里所述:将复杂的JSON发布到ASP。NET Core控制器暂时移除它让我可以继续前进。谢谢

共有2个答案

屠振濂
2023-03-14

我也偶然发现了这个问题。NET Core 2.1

似乎只有一个参数可以通过[FromBody]属性传递。您必须在一个对象中汇总所有参数。

Ajax调用示例:

 var data = {
                        messageIds: selectedIds,
                        read: true
                    };
                    $.ajax({
                        url: "@Url.Action("SetMessagesReadFlag", "Message")",
                        type: "POST",
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        data: JSON.stringify(data),
                        cache: false,
                        error: function(xhr, status, error) {
                            //do something about the error
                            alert(error);
                        },
                        success: function(response) {
                            if (response != null) {
                                grid.refresh();
                            }
                        }
                    });

具有虚拟助手类的控制器操作:

[HttpPost]

public IActionResult  SetMessagesReadFlag([FromBody] Dummy data)
{
    ....
    return Json(true);
}

public class Dummy
{
    public List<Guid> MessageIds { get; set; }

    public bool Read { get; set; }
}
仲璞瑜
2023-03-14

您实际上不是发送2个对象,而是发送一个包含2个其他对象的对象。这就是这一行,创建一个将要发送的对象。

data: JSON.stringify( { info: jsonObj, agreement: srFormJsonObj } ), // this is a single object that is created and sent by the http action

您需要在服务器上以相同的方式接收它,使用单个模型,然后包含您当前用作方法参数的2种类型。

型号代码

public class Model{
    public ApplicationInfoViewModel Info{get;set;} 
    public SRAgreementViewModel Agreement {get;set;}
}

控制器代码

public IActionResult Apply([FromBody]Model model)
{
     if(ModelState.IsValid){
     //do stuff. ModelState.IsValid returns false here.
     }
}

错误可能是因为您正在发送url编码数据和json,并在json对象中发送。您应该使用其中之一,但不能同时使用两者。如果查看最新更新,您可以看到为属性和协议发送的值,它们是表单编码的字符串值。

 类似资料:
  • 我试图从Web API返回Excel文件,但我得到的是JSON响应,而不是下载的文件。 这是我的AJAX调用 但我得到的回应是: {“version”:{“major”:1,“minor”:1,“build”:-1,“revision”:-1,“majorRevision”:-1,“minorRevision”:-1},“content”:{“headers”:[{“key”:“Content-D

  • .NET核心和ASP.NET核心到底有什么区别?

  • api文档没有说太多:https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/secretsmanager/misecretsmanageretsecretvalueasyncgetsecretvaluerequestcancellationtoken.html

  • 我读过关于.NET标准和.NET核心之间的区别,但我真的不知道区别是什么,也不知道什么时候选择.NET标准库项目,什么时候选择.NET核心库项目。

  • 19.2 核心与核心模块 谈完了整个开机的流程,您应该会知道,在整个开机的过程当中,是否能够成功的驱动我们主机的硬件配备, 是核心 (kernel) 的工作!而核心一般都是压缩文件,因此在使用核心之前,就得要将他解压缩后,才能载入内存当中。 另外,为了应付日新月异的硬件,目前的核心都是具有“可读取模块化驱动程序”的功能, 亦即是所谓的“ modules (模块化)”的功能啦!所谓的模块化可以将他想