在ASP.NET MVC站点中实现jQuery AJAX调用

时间:2010-06-22 23:58:12

标签: c# asp.net jquery asp.net-mvc asp.net-ajax

我正在构建一个ASP.NET MVC站点,我希望在某些地方实现jQuery AJAX调用。我已经阅读了这个主题,但仍然有一些问题。


模型绑定

首先,通过AJAX调用传递数据的正确方法是什么,并将其模型绑定到Controller Action中的对象中?

到目前为止,我已经在某些地方读过jQuery以键值对方式发送数据,因此我不需要做任何额外的事情,而在其他地方,我已经读过我必须首先使用JSON反序列化然后绑定结果。我目前已将控制器操作实现为接受HTTP POST的操作。

它是如何实际运作的?你能给我一些示例代码吗?


多个数据

接下来,如何发送多个数据?例如,我有一个提交注释的AJAX方法。在AJAX调用中,我想发送两个参数:一个ID参数(发表评论的帖子)和一个Text参数(评论的文本)。

我认为最好的方法是创建一个包含所有参数的类,然后通过AJAX调用发送类,绑定到Controller内部的相同类中。我是对的吗?


验证

最后,表单身份验证是通过这样的AJAX调用传输的吗?

如果用户已登录,是否会发送身份以便我可以像往常一样在我的控制器操作中使用它?

提前致谢。

2 个答案:

答案 0 :(得分:3)

您可以按照以下方式发布数据,这非常简单:

var formData = $(this).serialize()
        + "&Id=" + Id
        + "&otherVal=" + otherVal;

$.post($(this).attr("action"), formData, function(res)
{
    // do stuff with response

}, "json");

将ActionMethod定义为

public ActionResult MyAction(int id, string otherVal)
{
    return PartialView();
}

模型绑定器知道要将您传递给的参数名称与要绑定的变量相匹配。

或者您可以使用以下功能从所有选择下拉菜单中提取数据。表格上的复选框:

    // frm is $('form') that gets passed to the function
    // includeContextObjects determines if it's only the elements in the 
    // current form, or from all over the page.
    function GatherFormDataAndSubmit(frm, includeContextObjects)
    {

        var data = frm.serializeObject(); 
        data = GetSelectData(frm, data, includeContextObjects);
        data = GetCheckBoxData(frm, data, includeContextObjects);

        $.post(frm.attr("action"), data, function(res)
        {
            UpdateSuccessMessage(res);
        }, "json");
    }

    function GetSelectData(frm, data, includeContextObjects)
    {
        var objSelects;
        if (includeContextObjects)
        {
            objSelects = $("select");
        }
        else
        {
            objSelects = frm.find("select");
        }

        if (objSelects.length)
        {
            data = GetDataObjectFromSelects(objSelects, data);
        }

        return data;
    }


    function GetDataObjectFromSelects(selects, data)
    {

        var valuesArray = selects.map(function()
        {
            return $.getAttributes($(this).find(":selected"));
        });

        var obj = new Array();
        $.each(valuesArray, function(item) { obj.push($(this)[0]); });

        if (!data)
        {
            data = {};
        }
        $.each(obj, function()
        {
            for (var propertyName in $(this)[0])
            {
                data[propertyName] = $(this).attr(propertyName);
            }
        });

        return data;
    }

function GetCheckBoxData(frm, data, includeContextObjects)
{
    var objCheckBoxes;
    if (includeContextObjects)
    {
        objCheckBoxes = $("input:checked");
    }
    else
    {
        objCheckBoxes = frm.find("input:checked");
    }

    if (objCheckBoxes.length)
    {
        data = GetDataObjectFromCheckBoxes(objCheckBoxes, data);
    }

    return data;
}

function GetDataObjectFromCheckBoxes(objCheckBoxes, data)
{

    var valuesArray = objCheckBoxes.map(function()
    {
        return $.getAttributes($(this));
    });

    var obj = new Array();
    $.each(valuesArray, function(item) { obj.push($(this)[0]); });

    $.each(obj, function(i)
    {
        data["configuredFactsheets[" + i + "].configuredFactsheetId"] = $(this).attr("configuredFactsheetId");
    });

    return data;
}

注意,serializeObject()依赖于this,而getAttributes依赖于this

在这种情况下,我的行动方法是:

[AcceptVerbs(HttpVerbs.Post)]
public JsonResult EditConfiguredPanel(ConfiguredPanel cfp, List<ConfiguredFactsheet> configuredFactsheets) 
{

    bool success = repos.UpdateConfiguredPanel(cfp, configuredFactsheets);

    return Json(success);
}

其中List<ConfiguredFactsheet>的ID对应于使用GetCheckBoxData()收集的ID,而ConfiguredPanel的ID对应于从所选的选择列表选项中收集的ID。

修改此内容以包含评论文本和其他Id值不会花费太多。

表单身份验证数据将随每个请求以cookie的形式传输,所以是的。

答案 1 :(得分:1)

下面提供了一些示例代码。

好消息是,当你通过POST将一个键值对列表通过jquery传递给你的一个动作时,MVC框架将尽力将这些对映射到目标动作上的指定参数对象的实例中。这使得多个数据片段没有问题。关于身份验证,cookie与您的jquery POST一起传输,这应该允许您维护基于会话的表单安全性。

你会喜欢MVC /玩得开心!

客户端

// you can do this once to set defaults for later ajax transmissions
$.ajaxSetup({
    dataType: "json",
    type: "POST",
    cache: false,
    failure: failureOfAsyncCall,
    beforeSend: function() {
        $('div#ajaxProcessingMessageDiv').show();
    },
    complete: function() {
        $('div#ajaxProcessingMessageDiv').hide();
    }
});
// do something like this for each ajax transmission
$.ajax({
  data: "appId=" + $('#hAppId').val() +
                    "&functionalId=" + newVal.Dsc +
                    "&Dsc=" + newVal.Dsc2 + antiForgeryTokenData,
  url: '/App/SaveProfile', // App is my controller name here
  success: function(result) {
    // process your result - a json object in this case
  }
});

服务器端

[HttpPost]
public ActionResult SaveProfile(UpdatableAppInfo postData) {
  List<object> result = new List<object>();
  // process postData here
  return Json(result);
}