【问题标题】:Why is this AJAX call returning the entire page contents?为什么这个 AJAX 调用会返回整个页面内容?
【发布时间】:2012-12-08 02:13:58
【问题描述】:

我正在尝试调用在我的一个 aspx 页面文件中找到的以下 webmethod:

[WebMethod]
public static string GetReportDetails()
{
    var reportDetails = DataAccess.Database().GetBusinessInterestReportDetails(HttpContext.Current.User.Identity.Name);
    var json = BusinessInterestReport.GetJson(reportDetails); 
    return json;
}

这是我用来调用 webmethod 的 javascript:

 $.ajax({
      type: 'POST',
      url: 'SummaryReport.aspx/GetReportDetails',
      dataType: 'json',
      success: function (data) {
           alert(data);
      },
      error: function (jqXHR, textStatus, errorThrown) {
           alert('An error has occured: ' + errorThrown);
      }
 });

进行此 ajax 调用的 javascript:

$('.reportOption').click(function (e) {
    $.ajax({
      type: 'POST',
      url: 'SummaryReport.aspx/GetReportDetails',
      dataType: 'json',
      success: function (data) {
           alert(data);
      },
      error: function (jqXHR, textStatus, errorThrown) {
           alert('An error has occured: ' + errorThrown);
      }
 });
})

ScriptModule 配置已经在web.config 中。断点甚至没有在 webmethod 上被击中,而是返回了整个页面的内容。知道是什么原因造成的吗?

编辑: 使用 Chrome 的调试控制台我发现了这个错误:

[ArgumentException: Unknown web method GetReportDetails.
Parameter name: methodName]
   System.Web.Script.Services.WebServiceData.GetMethodData(String methodName) +516665
   System.Web.Handlers.ScriptModule.OnPostAcquireRequestState(Object sender, EventArgs eventArgs) +168
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

为什么不选择方法名?我还使用 <asp:ScriptManager ID="smMain" runat="server" EnablePageMethods="true" /> 启用了 PageMethods

附:刚刚意识到我是从 iFrame 中调用它的。这和问题有关系吗?

【问题讨论】:

  • 如果 webmethod 没有被点击,它是否返回了 500404 错误页面的代码?
  • 请显示包含您的按钮(或其他)的页面的 HTML
  • 变量json包含什么?
  • 我见过的大多数例子包括contentType: 'application/json; charset=utf-8'。这可能与它有关吗?
  • 您说您是在您的“aspx”文件中调用它 - 您是否在 ScriptManager 中启用了 PageMethods?

标签: c# jquery asp.net ajax webmethod


【解决方案1】:

根据我在这个问题上的经验,我想在这里贡献一个补充。 如果您使用的是内容页面或母版页,则无法通过访问该页面来调用 WebMethod,而是添加一个 web 服务页面并使用它,请参阅它与我一起使用的此链接。 http://forums.asp.net/post/5822511.aspx

我复制过来了

继承 System.Web.Services.WebService

<WebMethod()> _
Public Function MyFunction() As String
    Return "Hello World"
End Function

然后您可以从母版页或内容页调用 webmethod,如下所示:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
    function MyFunction() {
        var request = $.ajax({
            type: 'POST',
            url: 'HelloWord.asmx/MyFunction',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (serverdata) {
                alert("Done  " + serverdata);
            },
            error: function (error) {
                alert("error  ");
            }
        });
        return false;
    }
</script>

请务必取消注释该行: System.Web.Script.Services.ScriptService 在 web 服务页面中,因为在创建页面时它会被评论

【讨论】:

    【解决方案2】:

    修复它。事实证明,aspx 文件顶部缺少继承属性。

    所以现在我有:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SummaryReport.aspx.cs" MasterPageFile="~/MasterPages/SummaryReports.Master"
    Inherits="Web.SummaryReport"
        %>
    

    【讨论】:

      【解决方案3】:

      不要在您的 Web 方法中编写管道代码(JSON 序列化/反序列化)。只需获取/返回模型(.NET POCO 对象):

      [WebMethod]
      public static string GetReportDetails()
      {
          var reportDetails = DataAccess.Database().GetBusinessInterestReportDetails(HttpContext.Current.User.Identity.Name);
          return reportDetails;
      }
      

      然后消费:

      $.ajax({
          type: 'POST',
          url: 'SummaryReport.aspx/GetReportDetails',
          contentType: 'application/json',
          success: function (data) {
              // the actual object will be inside data.d
              var reportDetails = data.d;
              // Now you could directly use the properties of your model
              // For example if your ReportDetails .NET type had a string property
              // called FooBar you could directly alert(reportDetails.FooBar);
          },
          error: function (jqXHR, textStatus, errorThrown) {
              alert('An error has occured: ' + errorThrown);
          }
      });
      

      注意事项:

      • 我们已明确指定 contentType: 'application/json' 以向 Web 方法指示我们希望使用 JSON 作为传输机制
      • 我们已经摆脱了dataType: 'json' 属性,因为jQuery 足够智能,可以使用Content-Type 响应标头并自动解析传递给success 回调的data 参数。

      我还建议您阅读这篇关于 consuming ASP.NET PageMethods directly from jQuery 的文章。

      【讨论】:

        【解决方案4】:

        从您的 GetReportDetails 方法中删除 static 关键字。

        【讨论】:

          【解决方案5】:

          我认为你需要显式添加contentType,因为它的默认值是application/x-www-form-urlencoded; charset=UTF-8,这不是你想要的。

          所以你可能想稍微修改一下你的 jQuery 代码。

          $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "SummaryReport.aspx/GetReportDetails",
            dataType: "json",
            success: function (data) {
                alert(data);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert('An error has occured: ' + errorThrown);
            }
          });
          

          【讨论】:

          • 谢谢!这对我有帮助。我应该明白这一点...我没有明确设置我的 contentType。
          猜你喜欢
          • 1970-01-01
          • 2015-07-15
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          • 1970-01-01
          • 2018-09-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多