。Net-Core控制器操作不会绑定模型中的子复杂类型

问题描述 投票:0回答:3

这是我试图绑定模型的动作:

    [HttpPost]
    public JsonResult SaveNewBusiness(NewBusinessVm newBusiness)
    {

    }

这是模型:

    public class NewBusinessVm 
    {
       public NewBusinessVm()
       {

       }

    public int ID { get; set; }
    public string Name { get; set; }
    public ImageViewModel MainImage { get; set; }
    public string Description { get; set; }
    public List<SelectListItem> CategorySelections { get; set; }
    public int CategoryID { get; set; }
    public List<SelectListItem> LocationSelections { get; set; }
    public string LocationStr { get; set; }
    public List<int> FacilitiesIDs { get; set; }
    public string GoogleAddress { get; set; }
    public string FriendlyAddress { get; set; }
    public string GooglePlaceID { get; set; }
    public string Lat { get; set; }
    public string Long { get; set; }
    public int MinPrice { get; set; }
    public int MaxPrice { get; set; }
}

不会绑定的有问题的属性是MainImage

  public class ImageViewModel
    {
        public bool IsParent { get; set; }
        public string FileName { get; set; }
        public List<ImageViewModel> ChildImages { get; set; }
        public int? ImageFamilyId { get; set; }
        public string ImageUrl { get; set; }
        public string Title { get; set; }
        public string Alt { get; set; }
        public string Width { get; set; }
        public string Height { get; set; }
        public string Sizes { get; set; }
        public bool IsThumbNail { get; set; }
        public int Bytes { get; set; }
        public DateTime CreateTime { get; set; }
    }

我将MainImage添加到数据中。在客户端,我尝试了所有这三种方法:

        //#1
        var data = $form.serializeArray();
        data[data.length] = { name: "MainImage", value: mainImageObj };
        console.log(data);
        AjaxModule.Ajax(url, data, options);

        //#2
        var dataJson = JSON.stringify(data);
        console.log(dataJson);
        AjaxModule.Ajax(url, dataJson, options);

        //#3
        var data2 = $form.serialize();
        data2 += "&MainImage=" + JSON.stringify(mainImageObj);
        console.log(data2);
        AjaxModule.Ajax(url, data2, options);

第一个选项对象如下所示:enter image description here

第二个选项:

[{"name":"Name","value":"BusinessName example"},{"name":"CategoryID","value":"80"},{"name":"Description","value":""},{"name":"GooglePlaceID","value":"ChIJy9AOJGrKM5QR23I19T-HKD0"},{"name":"Long","value":""},{"name":"Lat","value":""},{"name":"GoogleAddress","value":"La Posta, Cordoba, Argentina"},{"name":"FriendlyAddress","value":"Río Primero,La Posta"},{"name":"__RequestVerificationToken","value":"CfDJ8E3zPSvylsxAsVq_mjBa9qQxnItdTOHxZje0mUebkKW5pH2K2ZUkB_Flg3XJsUQh_8hxmqGvUJo_hLuQIz6xOiFR1Y5HCDeGmGGKFSM2h1cHGfGkr7SBkIkZr4ImqCDRiaaRmy0x1taJyFmcqRpXMVSBnBN5pcjWkqqNhuGYL09KKD2xFJwk1Tbhcyb7d2YEPw"},{"name":"MainImage","value":{"IsParent":true,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":720,"Height":960,"CreateTime":"2020-04-24T11:24:04Z","Bytes":50450,"ChildImages":[{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_crop,g_auto,h_350,q_auto,w_1600/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":720,"Height":350,"CreateTime":"2020-04-24T11:24:04Z","Bytes":21629},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.8/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":576,"Height":768,"CreateTime":"2020-04-24T11:24:04Z","Bytes":38069},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.6/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":432,"Height":576,"CreateTime":"2020-04-24T11:24:04Z","Bytes":25138},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.4/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":288,"Height":384,"CreateTime":"2020-04-24T11:24:04Z","Bytes":14803},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.2/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":144,"Height":192,"CreateTime":"2020-04-24T11:24:04Z","Bytes":5285,"IsThumbnail":true}]}}]

第三选项:

Name=BusinessName%20example&CategoryID=80&Description=&GooglePlaceID=ChIJy9AOJGrKM5QR23I19T-HKD0&Long=&Lat=&GoogleAddress=La%20Posta%2C%20Cordoba%2C%20Argentina&FriendlyAddress=R%C3%ADo%20Primero%2CLa%20Posta&__RequestVerificationToken=CfDJ8E3zPSvylsxAsVq_mjBa9qQxnItdTOHxZje0mUebkKW5pH2K2ZUkB_Flg3XJsUQh_8hxmqGvUJo_hLuQIz6xOiFR1Y5HCDeGmGGKFSM2h1cHGfGkr7SBkIkZr4ImqCDRiaaRmy0x1taJyFmcqRpXMVSBnBN5pcjWkqqNhuGYL09KKD2xFJwk1Tbhcyb7d2YEPw&MainImage={"IsParent":true,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":720,"Height":960,"CreateTime":"2020-04-24T11:24:04Z","Bytes":50450,"ChildImages":[{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_crop,g_auto,h_350,q_auto,w_1600/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":720,"Height":350,"CreateTime":"2020-04-24T11:24:04Z","Bytes":21629},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.8/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":576,"Height":768,"CreateTime":"2020-04-24T11:24:04Z","Bytes":38069},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.6/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":432,"Height":576,"CreateTime":"2020-04-24T11:24:04Z","Bytes":25138},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.4/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":288,"Height":384,"CreateTime":"2020-04-24T11:24:04Z","Bytes":14803},{"IsParent":false,"ImageUrl":"https://res.cloudinary.com/dzpwse6vo/image/upload/c_scale,q_auto,w_0.2/v1587727444/Businesses/44637/noyc0lpgto9t2p1j15kx.jpg","FileName":"Businesses/44637/noyc0lpgto9t2p1j15kx","Width":144,"Height":192,"CreateTime":"2020-04-24T11:24:04Z","Bytes":5285,"IsThumbnail":true}]}

我试图将签名更改为public JsonResult SaveNewBusiness([FromBody]NewBusinessVm newBusiness)

并且也要:public JsonResult SaveNewBusiness([FromForm]NewBusinessVm newBusiness)

除此属性外,所有属性均按预期方式绑定。任何帮助,有可能吗?

c# asp.net-core .net-core asp.net-core-2.0
3个回答
0
投票

您的json格式为不正确

您必须将json更改为此

{
  "MainImage": {
    "IsParent": true,
    "ImageUrl": "https://res.cloudinary.com/dzpws1e6vo/image/upload/v1587657844/Businesses/44637/q1lgkqgwpwp7zy1obtpwn.jpg",
    "FileName": "Businesses/44637/qlgkqgwpwp7zy11obtpwn",
    "Width": 960,
    "Height": 720,
    "CreateTime": "2020-04-23T16:04:04Z",
    "Bytes": 181783,
    "ChildImages": [{
        "IsParent": false,
        "ImageUrl": "https://res.cloudinary.com/dzpwse6vo/image/upload/c_crop,g_auto,h_350,q_auto,w_1600/v15876517844/Businesses/44637/qlgkqgwpwp7zy1o1btpwn.jpg",
        "FileName": "Businesses/44637/qlgkqgwpwp7z1y1obtpwn",
        "Width": 960,
        "Height": 350,
        "CreateTime": "2020-04-23T16:04:04Z",
        "Bytes": 78322
    }]
}

或将输入模型更改为此

[HttpPost]
public JsonResult SaveNewBusiness(ImageViewModel imageViewModel)
{

}

0
投票

您正在混合和匹配这些东西。表单将以x-www-form-urlencoded的形式发送,基本上就是字符串键值对。将JSON对象设置为这些对之一的值时,以这种方式发送JSON不会导致将JSON反序列化为对象,因为不知道或以任何方式表明它是JSON。和其他字符串一样,它只是一个字符串。此外,这里的整个对象无论如何都不会绑定,因为FromBody需要类似application/json的东西,而不是x-www-form-urlencoded。对于后者,您需要FromForm

[如果要接受JSON,则需要使用AJAX发送帖子(因为HTML表单无法执行此操作),并且您实际上需要将其编码为JSON而不是使用隐藏发送输入以类似JSON的字符串作为值。

如果要继续通过表单发布,则需要在主图像上包括每个属性的输入(而不是仅以整个对象作为值的一个输入),或者您需要将其绑定到字符串属性,然后手动返回并自己反序列化为对象。


0
投票

通常,当我发布一个没有复杂对象的表单时,我会像这样:

var data = $form.serialize();
AjaxModule.Ajax(url, data, options);

但是由于对象很复杂,我不得不像这样为干净的javascript对象形成输入:

    //#1 form elements into name:value object
    var data = $form.serializeArray();
    data[data.length] = { name: "MainImage", value: mainImageObj };

    //#2 Create a clean JS Object
    var myObj = {};
    for (var j = 0; j < data.length; j++) {
        myObj[data[j]["name"]] = data[j]["value"];
    }

    AjaxModule.Ajax(url, myObj, options);

工作!谢谢Partick(aka:poke)

© www.soinside.com 2019 - 2024. All rights reserved.