使用Jquery/Ajax将模型传递给控制器

43

我正在尝试使用JQuery / Ajax将我的模型传递给控制器,但我不确定如何正确操作。到目前为止,我尝试使用Url.Action,但模型为空。

注意:stackoverflow上的重复线程似乎都没有涉及到ASP.NET 5 MVC 6的使用。

视图:

$("#inpDateCompleted").change(function () {
        var url = '@(Url.Action("IndexPartial", "DashBoard", Model, null))';
        $("#DailyInvoiceItems").load(url);
});

控制器:

 [HttpGet]
 public PartialViewResult IndexPartial(DashBoardViewModel m)
 {
      // Do stuff with my model
      return PartialView("_IndexPartial");
 }

1
这仅会传递原始模型 (Url.Action() 是服务器端解析后发送到视图的 Razor 代码)。如果你只想将所选日期发送到方法,请使用 $("#DailyInvoiceItems").load('@(Url.Action("IndexPartial", "DashBoard"))', { date: $(yourdatecontrol).val() }); 并且更改方法来带有一个 DateTime date 参数。 - user3559349
2
你可以使用 $('form').serialize() 来序列化你表单中的所有控件。例如:$.post('@(Url.Action("IndexPartial", "DashBoard"), $('form').serialize(), function(data) { $("#DailyInvoiceItems").html(data); }); - user3559349
好的,但是在我的PartialViewResult方法中,我怎么把它转换回强类型模型呢? - Reafidy
1
这就是 $('form').serialize() 的作用。假设您已经正确生成了表单控件,您的 DashBoardViewModel m 参数将被正确绑定。 - user3559349
1
那意味着你真的应该使用视图模型(即仅包含视图中所需的属性),但是不,你排除的任何属性在方法中将只是它们的默认值。 - user3559349
显示剩余6条评论
4个回答

84

看起来你的IndexPartial操作方法有一个复杂对象参数。如果你正在传递大量数据(复杂对象),将操作方法转换为HttpPost操作方法,并使用jQuery的post方法将数据提交可能是个好主意。GET在查询字符串值方面有限制。

[HttpPost]
public PartialViewResult IndexPartial(DashboardViewModel m)
{
   //May be you want to pass the posted model to the parial view?
   return PartialView("_IndexPartial");
}

你的脚本应该是

var url = "@Url.Action("IndexPartial","YourControllerName")";

var model = { Name :"Shyju", Location:"Detroit"};

$.post(url, model, function(res){
   //res contains the markup returned by the partial view
   //You probably want to set that to some Div.
   $("#SomeDivToShowTheResult").html(res);
});

假设您的 DashboardViewModel 类具有属性 NameLocation,并且 SomeDivToShowTheResult 是页面上一个 div 的 id,您想要在其中加载来自 partialview 的内容。

发送复杂对象?

如果需要,您可以在 js 中构建更复杂的对象。只要结构与视图模型类匹配,模型绑定就会起作用。

var model = { Name :"Shyju", 
              Location:"Detroit", 
              Interests : ["Code","Coffee","Stackoverflow"]
            };

$.ajax({
    type: "POST",
    data: JSON.stringify(model),
    url: url,
    contentType: "application/json"
}).done(function (res) {
    $("#SomeDivToShowTheResult").html(res);
});

为了将上述js模型转换为您的方法参数,您的视图模型应该像这样。

public class DashboardViewModel
{
  public string Name {set;get;}
  public string Location {set;get;}
  public List<string> Interests {set;get;}
}

在您的操作方法中,指定 [FromBody]

[HttpPost]
public PartialViewResult IndexPartial([FromBody] DashboardViewModel m)
{
    return PartialView("_IndexPartial",m);
}

谢谢,我理解了关于Post/Get的内容,但是在你的代码中,似乎只是发布了模型的一个参数,难道不能传递整个模型吗?整个DashboardVIewModel。 - Reafidy
@ Reafidy 请查看下面的完整实现 - Julius Depulla
2
@Reafidy 很酷。请查看https://dev59.com/3mIj5IYBdhLWcg3weE-q#20226220,以获取有关将模型发布到控制器的更详细说明。 - Shyju
jQuery能否从PartialView中读取模型参数并返回呢?例如,我想创建一个新元素并读取控制器传回的新模型ID以添加其他DOM元素。我知道我可以将其包含在PartialView中,但如果我想要与PartialView无关的另一部分的ID,该怎么办呢? - Allen Wang

15

使用以下JS代码:

$(document).ready(function () {
    $("#btnsubmit").click(function () {

             $.ajax({
                 type: "POST",
                 url: '/Plan/PlanManage',     //your action
                 data: $('#PlanForm').serialize(),   //your form name.it takes all the values of model               
                 dataType: 'json',
                 success: function (result) {
                     console.log(result);
                 }
             })
        return false;
    });
});

在你的控制器中添加以下代码:

[HttpPost]
public string PlanManage(Plan objplan)  //model plan
{
}

2
在你的代码中添加一些解释,以便答案更具可重用性。 - Imran Saeed
这种技术对我来说非常简单而有效。我将ajax调用放在了一个带有JavaScript的ActionLink上,而不是提交按钮上。 - Dave

8

如其他答案所建议的那样,最简单的方法可能是将表单数据“POST”到控制器。如果您需要传递整个模型/表单,您可以轻松使用 serialize() 完成这项工作,例如:

$('#myform').on('submit', function(e){
    e.preventDefault();

    var formData = $(this).serialize();

    $.post('/student/update', formData, function(response){
         //Do something with response
    });
});

因此,您的控制器可以将视图模型作为参数,例如:

 [HttpPost]
 public JsonResult Update(StudentViewModel studentViewModel)
 {}

或者,如果您只想发布一些特定的值,可以执行以下操作:

$('#myform').on('submit', function(e){
    e.preventDefault();

    var studentId = $(this).find('#Student_StudentId');
    var isActive = $(this).find('#Student_IsActive');

    $.post('/my/url', {studentId : studentId, isActive : isActive}, function(response){
         //Do something with response
    });
});

使用这样的控制器:

     [HttpPost]
     public JsonResult Update(int studentId, bool isActive)
     {}

7
//C# class

public class DashBoardViewModel 
{
    public int Id { get; set;} 
    public decimal TotalSales { get; set;} 
    public string Url { get; set;} 
     public string MyDate{ get; set;} 
}

//JavaScript file
//Create dashboard.js file
$(document).ready(function () {

    // See the html on the View below
    $('.dashboardUrl').on('click', function(){
        var url = $(this).attr("href"); 
    });

    $("#inpDateCompleted").change(function () {   

        // Construct your view model to send to the controller
        // Pass viewModel to ajax function 

        // Date
        var myDate = $('.myDate').val();

        // IF YOU USE @Html.EditorFor(), the myDate is as below
        var myDate = $('#MyDate').val();
        var viewModel = { Id : 1, TotalSales: 50, Url: url, MyDate: myDate };


        $.ajax({
            type: 'GET',
            dataType: 'json',
            cache: false,
            url: '/Dashboard/IndexPartial',
            data: viewModel ,
            success: function (data, textStatus, jqXHR) {
                //Do Stuff 
                $("#DailyInvoiceItems").html(data.Id);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                //Do Stuff or Nothing
            }
        });

    });
});

//ASP.NET 5 MVC 6 Controller
public class DashboardController {

    [HttpGet]
    public IActionResult IndexPartial(DashBoardViewModel viewModel )
    {
        // Do stuff with my model
        var model = new DashBoardViewModel {  Id = 23 /* Some more results here*/ };
        return Json(model);
    }
}

// MVC View 
// Include jQuerylibrary
// Include dashboard.js 
<script src="~/Scripts/jquery-2.1.3.js"></script>
<script src="~/Scripts/dashboard.js"></script>
// If you want to capture your URL dynamically 

<div>
    <a class="dashboardUrl" href ="@Url.Action("IndexPartial","Dashboard")"> LinkText </a>
</div>
<div>
    <input class="myDate" type="text"/>
//OR
   @Html.EditorFor(model => model.MyDate) 
</div>

@NEDian 感谢您的缩进。 - Julius Depulla
好的,抱歉 - 最后一个问题,我如何让ajax查询的结果加载到“#DailyInvoiceItems” DIV中? - Reafidy
使用“text”无效,我添加了完整的控制器代码以帮助理解我想要做什么。 - Reafidy
您需要使用JsonRequestBehavior.AllowGet来允许从控制器返回json对象到视图。出于安全原因,它在ASP.NET MVC 5中被禁用,但如果您需要返回json数据,这就是启用它的方法。 - Julius Depulla
我不认为你提供的链接文章会有所帮助。没有需要添加的依赖项。System.Web.MVC将无法与asp.net 5一起使用。 - Reafidy
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接