C# 使用jQueryAjax,如何发布包含其他对象列表的对象

C# 使用jQueryAjax,如何发布包含其他对象列表的对象,c#,jquery,ajax,asp.net-web-api,C#,Jquery,Ajax,Asp.net Web Api,给定这些C对象 class foo { int fooId {get; set;} string fooName {get;set;} List<bar> bars {get; set;} } class bar { int barId {get; set;} string barName {get;set;} } 假设我们有一个表单,其中用户输入fooName和一个条形项目列表,那么从表单序列化数据并将其提交给WebApi方法的最佳方式

给定这些C对象

class foo 
{
    int fooId {get; set;}
    string fooName {get;set;}
    List<bar> bars {get; set;}
}

class bar
{
    int barId {get; set;}
    string barName {get;set;}
}

假设我们有一个表单,其中用户输入fooName和一个条形项目列表,那么从表单序列化数据并将其提交给WebApi方法的最佳方式是什么?

我强烈建议只需创建一个带有

<form id="f">
@Html.TextBoxFor(x=>x.foo);
@for(var i = 0; i<Model.foo.bars.Length; i++){
    @Html.TextBoxFor(x=>x.foo.bars[i]);
}
</form>

$(document).ready(function(){
    console.log($('#f').serialize());
});

因此,您可以看到预期的结构。然后您可以按照自己的意愿填充JSON,我找不到一种方法在一个ajax调用和一个WebApi控制器操作中发布foo和条列表。我以两篇ajax文章和两个控制器操作结束。两次旅行,而不是一次,但它的工作。下面是我的解决方案,以防任何人发现它有用

在html方面,我对表单使用了两个div,因为这是Asp.NETWebForms,这意味着我们只能使用一个表单

<div id="foo-form">
    <input type="text" name="fooName" value="" />
    <button type="button" class="btn-cancel">Cancel</button>
    <button type="button" class="btn-submit">Submit</button>
</div>

<div id="bar-form">
    <input type="text" class="foobar" value="" />
    <input type="text" class="foobar" value="" />
    <input type="text" class="foobar" value="" />
    <input type="text" class="foobar" value="" />
</div>
现在是服务器端的webapi控制器C代码

[HttpPost]
public HttpResponseMessage AddFoo(Foo model)
{
    try
    {
        //validate
        if (!ModelState.IsValid)
            return Request.CreateResponse(HttpStatusCode.OK, new { Status = "error", Message = "Error in foo"});
        //save foo
        var db = new FooBarDB();
        var id = db.AddFoo(model);
        //return new fooId
        return Request.CreateResponse(HttpStatusCode.OK, new { Status = "success", Id = id });
    }
    catch (Exception ex)
    {                
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }
}

[HttpPost]
public HttpResponseMessage AddBars(List<Bar> bars)
{
    try
    {
        //validate bars
        if (!this.ValidateBars(bars))
            return Request.CreateResponse(HttpStatusCode.OK, new { Status = "error", Message = "Errors in bars"});
        //save bars
        var db = new FooBarDB();
        db.AddBars(bars);
        //show success
        return Request.CreateResponse(HttpStatusCode.OK, new { Status = "success"});
    }
    catch (Exception ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }
}

private bool ValidateBars(List<Bar> bars)
{
    //logic to validate bars
}

多个表单不起作用,因为这不是asp.net mvc,而是带有webapi webservices的asp.net webforms应用程序。我一直在寻找一种ajax方法来发布foo和条列表,以及一种webapi方法来从浏览器接收您的答案没有提到的数据。
$("#foo-form .btn-submit").click(function (e) {
    e.preventDefault();
    fooBar.saveFoo();
});

var fooBar = new function () {

    //this posts foo
    this.saveFoo = function () {
        // serialize the form
        var serializedData = $("#foo-form :input").serialize();

        $.ajax({
            type: "POST",
            url: "/myapp/api/FooBar/AddFoo",
            data: serializedData,
            cache: false
        }).done(function (data) {
            if (data["Status"] === 'success') {
                //pass the id to the saveBars function
                fooBar.saveBars(data["Id"])
            }
            else {
                //handle logic error
            }
        }).fail(function (xhr, textStatus, errorThrown) {
            //handle ajax error
        }).always(function () {
            //something to do always
        });
    }


    //this posts bars
    this.saveBars = function (fooId) {

        //save all bars in array
        var arrBars = [];
        $('#bar-form .foobar').each(function () {
            arrBars.push(
                    {
                        "fooId": fooId,
                        "fooName": $(this).val()
                    }
                );
        });

        $.ajax({
            type: "POST",
            url: "/myapp/api/FooBar/AddBars",
            data: JSON.stringify(arrBars),
            cache: false,
            contentType: "application/json; charset=utf-8"
        }).done(function (data) {
            if (data["Status"] === 'success') {
                //show success message
            }
            else {
                //handle logic error
            }
        }).fail(function (xhr, textStatus, errorThrown) {
            //handle ajax error
        }).always(function () {
            //something to do always
        });
    }
}
[HttpPost]
public HttpResponseMessage AddFoo(Foo model)
{
    try
    {
        //validate
        if (!ModelState.IsValid)
            return Request.CreateResponse(HttpStatusCode.OK, new { Status = "error", Message = "Error in foo"});
        //save foo
        var db = new FooBarDB();
        var id = db.AddFoo(model);
        //return new fooId
        return Request.CreateResponse(HttpStatusCode.OK, new { Status = "success", Id = id });
    }
    catch (Exception ex)
    {                
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }
}

[HttpPost]
public HttpResponseMessage AddBars(List<Bar> bars)
{
    try
    {
        //validate bars
        if (!this.ValidateBars(bars))
            return Request.CreateResponse(HttpStatusCode.OK, new { Status = "error", Message = "Errors in bars"});
        //save bars
        var db = new FooBarDB();
        db.AddBars(bars);
        //show success
        return Request.CreateResponse(HttpStatusCode.OK, new { Status = "success"});
    }
    catch (Exception ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }
}

private bool ValidateBars(List<Bar> bars)
{
    //logic to validate bars
}