【问题标题】:Passing response from ajax call to view in C#将来自 ajax 调用的响应传递给 C# 中的视图
【发布时间】:2014-12-01 08:43:20
【问题描述】:

我正在使用 ajax 来调用控制器中的操作。代码是这样的

   $('#kitchen').change(function () {
    var selectedKitchen = $('#kitchen').val();
    if (selectedKitchen != '') {
        console.log("selected item:" + $('#kitchen').val());
        $.ajax({
            type: "GET",
            url: "/Home/GiveInsitutionsWithoutResponsibility",
            data: "id=" + selectedKitchen,
            dataType:'json',
            success: function (result) {
                result = JSON.parse(result);
                console.log(result.length);
            },
            error: function (error) {
                console.log("There was an error posting the data to the server: ");
                console.log(error.responseText);
            }
        });
    }

});

现在我想要的是使用来自服务器的结果来填充客户端的下拉列表。我该怎么做?有没有办法或者我的方法是错误的?

我的结果对象是这样的

{
Id: "04409314-ea61-4367-8eee-2b5faf87e592"
Name: "Test Institution Two"
NextPatientId: 1
OwnerId: "1"
PartitionKey: "1"
RowKey: "04409314-ea61-4367-8eee-2b5faf87e592"
Timestamp: "/Date(1417180677580)/"
}

控制器功能是这样的

    public ActionResult GiveInsitutionsWithoutResponsibility()
    {
        var kitchenId = Request["id"].ToString();
        Kitchen k = Kitchen.Get(kitchenId);
        IEnumerable <Institution> ins = k.GetInstitutions();
        IEnumerable<Institution> allIns = Institution.GetAll();
        List<Institution> result = new List<Institution>();
        bool contain = true;
        int index = 0;
        if (ins.Count() > 0)
        {
            for (int i = 0; i < allIns.Count(); i++, contain = true)
            {
                for (int j = 0; j < ins.Count(); j++)
                {
                    if (allIns.ElementAt(i).Id == ins.ElementAt(j).Id)
                    {
                        contain = true;
                        break;
                    }
                    else
                    {
                        index = j;
                        contain = false;
                    }
                }
                if (!contain)
                {
                    result.Add(allIns.ElementAt(index));
                }
            }
        }
        else
        {
            for (int i = 0; i < allIns.Count(); i++)
            {
                result.Add(allIns.ElementAt(index));
            }
        }
        string response = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(result);
        return Json(response, JsonRequestBehavior.AllowGet);

    }

【问题讨论】:

  • 您错过了dataType:'json',,您可以参考$('#kitchen')$(this),这将是一个好方法。
  • 谢谢。我已经编辑了我的代码,但是关于如何使用结果对象有什么建议吗?
  • 你的result object到底是​​什么?你能把它贴出来看看它有什么结构吗?
  • 刚刚编辑了带有回复的问题。
  • 似乎是一个无效对象。检查jsonlint.com,尤其是这里ETag: "W/"datetime'2014-11-28T13%3A17%3A57.58Z'"",对象中的第一个。

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


【解决方案1】:

首先你的动作方法可以简化为

public ActionResult GiveInsitutionsWithoutResponsibility(int ID)
{
  Kitchen k = Kitchen.Get(ID);
  var data = Institution.GetAll().Except(k.GetInstitutions(), new InstitutionComparer()).Select(i => new
  {
    ID = i.ID,
    Name = r.Name
  });
  return Json(data, JsonRequestBehavior.AllowGet);
}

注意Kitchen.ID 是在方法参数中传递的。 Linq 查询用于选择所有Institution,然后排除Institution 中已经存在的任何Kitchen,然后创建匿名对象的集合,这样不必要的数据就不会发送到客户端。 Json() 方法以正确的 JSON 格式返回数据(不需要调用 JavaScriptSerializer().Serialize())。

为了让.Except() 处理复杂对象,您需要一个比较器

public class InstitutionComparer : IEqualityComparer<Institution>
{
  public bool Equals(Institution x, Institution y)
  {
    if (Object.ReferenceEquals(x, y)) 
    {
      return true;
    }
    if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
    {
        return false;
    }
    return x.ID == y.ID;
  }
  public int GetHashCode(Institution institution)
  {
    if (Object.ReferenceEquals(institution, null))
    {
      return 0; 
    }
    return institution.ID.GetHashCode();
  }
}

接下来将ajax方法改为

$('#kitchen').change(function () {     
  var selectedKitchen = $('#kitchen').val();
  if (!selectedKitchen) {
    return;
  }
  $.ajax({
    type: "GET",
    url: '@Url.Action("GiveInsitutionsWithoutResponsibility", "Home")', // don't hard code urls
    data: { id: selectedKitchen }, // pass selectedKitchen to the id parameter
    dataType:'json',
    success: function (result) {
      var select = $('YourDropDownSelector').empty().append($('<option></option>').val('').text('--Please select--'));
      $.each(result, function(index, item) {
        select.append($('<option></option>').val(item.ID).text(item.Name));
      });
    },
    error: function (error) {
    }
  });
});

或者你可以使用捷径

$.getJSON('@Url.Action("GiveInsitutionsWithoutResponsibility", "Home")', { id: selectedKitchen }, function(result) {
  $.each(result, .... // as above
});

【讨论】:

  • 非常感谢。但它还给我所有的机构。 except 子句不起作用。
  • 啊,那可能是因为你没有覆盖.Equals()。让我检查一下在这种情况下需要什么。
  • 当然..期待解决方案。
  • @mohsinali1317,事实证明,如果没有比较器,这并不容易。我已经习惯了用我所有的东西做这件事,我忘记了其他人不这样做:)。我已经用比较器(和Except() 子句)更新了代码
【解决方案2】:

根据您的控制器中的对象,您可以遍历您的结果数据和.append 这个到您的下拉列表。

success: function (result) {

   $.each(result, function(index, manager) {
       $('select#yourId').append(
               '<option value="' + result.Id + '">'
                    + result.Name + 
       '</option>');
   });

}

【讨论】:

  • 我知道这种方法,但我希望 ASP.NET MVC 有它的功能,就像 razor 有一些功能一样。
  • 啊,对不起,伙计!我没有立即意识到 razor 中已经内置了一些东西,但您可以使用自定义帮助器,helper link希望这会有所帮助。
  • @MattWebb,不,您不能使用 html 助手。 Razor 在页面发送到浏览器之前在服务器上进行解析。
  • @Stephen Muecke 我的意思是代替 ajax,然后您可以在局部视图中返回它。
【解决方案3】:

您的方法很好,您必须格式化要添加到组合框的结果。例如,支持在我有国家和州组合框的页面上。根据选定的国家,我需要填充状态,所以我将编写以下代码:

    $("#billingContactCountry").change(function (e) {
        e.preventDefault();

        var countryId = $("#billingContactCountry").val();

        getStatesByCountry(countryId, "", "#billingContactState", "#billingContactZip");
    });

    function getStatesByCountry(countryId, stateId, stateCombobox, zipTextBox) {

    $.ajax({
        url: "@Url.Action("GetStatesByCountry", "Admin")",
        data: { countryId: countryId },
        dataType: "json",
        type: "GET",
        error: function (xhr, status) {
            //debugger;
            var items = "<option value=\"\">-Select State-</option>";
            $(stateCombobox).html(items);

            var zipMessage = validateZip(countryId, $(zipTextBox).val());
            if (zipMessage != "The ZIP Code field is required.") {
                $(zipTextBox).parent().find("span.field-validation-error").text(zipMessage);
            }

            $("div.overlay").hide();
        },
        success: function (data) {
            //debugger;
            var items = "<option value=\"\">-Select State-</option>";
            $.each(data, function (i, item) {
                items += "<option value=\"" + item.Id + "\">" + item.Name + "</option>";
            });

            $(stateCombobox).html(items);

            if (stateId != "") {
                $('#billingContactState').val(stateId);
            }

            var zipMessage = validateZip(countryId, $(zipTextBox).val());
            if (zipMessage != "The ZIP Code field is required.") {
                $(zipTextBox).parent().find("span.field-validation-error").text(zipMessage);
            }

            $("div.overlay").hide();
        }
    });
}

所以基本上有趣的代码是,

            var items = "<option value=\"\">-Select State-</option>";
            $.each(data, function (i, item) {
                items += "<option value=\"" + item.Id + "\">" + item.Name + "</option>";
            });

            $(stateCombobox).html(items);

我们正在对从服务器返回的每个元素进行操作,以创建组合框的选项项。

顺便说一句,您应该使用@Url.Action,如上例所示。

【讨论】:

  • 我知道这种方法,但我希望 ASP.NET MVC 有它的功能,就像 razor 有一些功能一样。
  • @mohsinali1317 - 很高兴您知道这种方法。您为什么不在您的问题中添加它以及您“希望”作为解决方案。
猜你喜欢
  • 2016-11-06
  • 2012-10-02
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多