使用Jsonp调用跨域Asp.Net Web服务

时间:2012-09-21 17:42:36

标签: jquery asp.net ajax web-services jsonp

我尝试了无数的例子,无法让它发挥作用。

我正在尝试调用跨域asp.net Web服务,但每次都会收到以下错误:

  

jQuery18105929389187970706_1348249020199未被调用

这是我的网络服务:

[WebService(Namespace = "http://www.mywebsite.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
[ScriptService]
public class DataService : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
    public string GetIncidentsByAddress()
    {
        return "It worked!";
    }
}

我的HttpModule来处理Json:

 public class JsonHttpModule : IHttpModule
    {
        private const string JSON_CONTENT_TYPE = "application/json; charset=utf-8";

        public void Dispose()
        {
        }

        public void Init(HttpApplication app)
        {
            app.BeginRequest += OnBeginRequest;
            app.ReleaseRequestState += OnReleaseRequestState;
        }

        bool _Apply(HttpRequest request)
        {
            if (!request.Url.AbsolutePath.Contains(".asmx")) return false;
            if ("json" != request.QueryString.Get("format")) return false;
            return true;
        }

        public void OnBeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;

            if (!_Apply(app.Context.Request)) return;

            // correct content type of request
            if (string.IsNullOrEmpty(app.Context.Request.ContentType))
            {
                app.Context.Request.ContentType = JSON_CONTENT_TYPE;
            }
        }

        public void OnReleaseRequestState(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;

            if (!_Apply(app.Context.Request)) return;

            // apply response filter to conform to JSONP
            app.Context.Response.Filter =
                new JsonResponseFilter(app.Context.Response.Filter, app.Context);
        }
    }

    public class JsonResponseFilter : Stream
    {
        private readonly Stream _responseStream;
        private HttpContext _context;

        public JsonResponseFilter(Stream responseStream, HttpContext context)
        {
            _responseStream = responseStream;
            _context = context;
        }

        //...

        public override void Write(byte[] buffer, int offset, int count)
        {
            var b1 = Encoding.UTF8.GetBytes(
              _context.Request.Params["callback"] + "(");
            _responseStream.Write(b1, 0, b1.Length);
            _responseStream.Write(buffer, offset, count);
            var b2 = Encoding.UTF8.GetBytes(");");
            _responseStream.Write(b2, 0, b2.Length);
        }

        //...
    }

我所说的HttpModule的web.config:

<add name="JSONAsmx" type="JsonHttpModule, App_Code"/>

最后我的jQuery调用:

<script src="js/jquery.jmsajax.min.js" type="text/javascript"></script>
<script src="js/jquery-1.8.1.min.js" type="text/javascript"></script>

<script type="text/javascript">

    $.jmsajaxurl = function(options) {
        var url = options.url;
        url += "/" + options.method;
        if (options.data) {
            var data = ""; for (var i in options.data) {
                if (data != "")
                    data += "&"; data += i + "=" +
             msJSON.stringify(options.data[i]);
            }
            url += "?" + data; data = null; options.data = "{}";
        }
        return url;
    };

    $(function() {
        var url = $.jmsajaxurl({
            url: "http://www.mywebsite.org/apps/IncidentReportingService/DataService.asmx",
            method: "GetIncidentsByAddress",
            data: {}
        });

        $.ajax({
            cache: false,
            dataType: "jsonp",
            success: function(data) { successCallback(data); },
            error:function(xhr, status, errorThrown) { debugger;},
            url: url + "&format=json"
        });

    });

    function successCallback(data) {
        debugger;
        $.each(data, function(i, item) {
            $("#tweets ul").append("<li>" + item.text + "</li>");
        });
    };

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

尝试解析json返回的数据,如下所示

success: function(data) { 
    data = JSON.parse(data); 
    // Do work with the data
}

答案 1 :(得分:0)

看来我的HttpModule并没有一直实现。有一些方法我没有覆盖它,它导致整个Web服务无法工作。

我将其更改为以下内容,现在一切正常:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;

public class JsonHttpModule : IHttpModule
{
    private const string JSON_CONTENT_TYPE = "application/json; charset=utf-8";

    public void Dispose()
    {
    }

    public void Init(HttpApplication app)
    {
        app.BeginRequest += OnBeginRequest;
        app.ReleaseRequestState += OnReleaseRequestState;
    }

    bool _Apply(HttpRequest request)
    {
        if (!request.Url.AbsolutePath.Contains(".asmx")) return false;
        if ("json" != request.QueryString.Get("format")) return false;
        return true;
    }

    public void OnBeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (!_Apply(app.Context.Request)) return;

        // correct content type of request
        if (string.IsNullOrEmpty(app.Context.Request.ContentType))
        {
            app.Context.Request.ContentType = JSON_CONTENT_TYPE;
        }
    }

    public void OnReleaseRequestState(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (!_Apply(app.Context.Request)) return;

        // apply response filter to conform to JSONP
        app.Context.Response.Filter =
            new JsonResponseFilter(app.Context.Response.Filter, app.Context);
    }
}

public class JsonResponseFilter : Stream
{
    private readonly Stream _responseStream;
    private HttpContext _context;
    private long _position;

    public JsonResponseFilter(Stream responseStream, HttpContext context)
    {
        _responseStream = responseStream;
        _context = context;
    }

    public override bool CanRead { get { return true; } }

    public override bool CanSeek { get { return true; } }

    public override bool CanWrite { get { return true; } }

    public override long Length { get { return 0; } }

    public override long Position { get { return _position; } set { _position = value; } }

    public override void Write(byte[] buffer, int offset, int count)
    {
        var b1 = Encoding.UTF8.GetBytes(
          _context.Request.Params["callback"] + "(");
        _responseStream.Write(b1, 0, b1.Length);
        _responseStream.Write(buffer, offset, count);
        var b2 = Encoding.UTF8.GetBytes(");");
        _responseStream.Write(b2, 0, b2.Length);
    }

    public override void Close()
    {
        _responseStream.Close();
    }

    public override void Flush()
    {
        _responseStream.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _responseStream.Seek(offset, origin);
    }

    public override void SetLength(long length)
    {
        _responseStream.SetLength(length);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _responseStream.Read(buffer, offset, count);
    }
}