我怎么能生产出JSONP从跨域调用的ASP.NET Web服务?(How can I produce

2019-07-18 00:22发布

我写了一个web服务返回JSON和我试着使用jQuery这样称呼它:

$.ajax({
    contentType: "application/json; charset=utf-8",
    url: "http://examplewebsite.com/service.asmx/GetData",
    data: { projectID: 1 },
    dataType: "jsonp",
    success: function () {alert("success");}
});

然而,代码永远不会尽管Web服务调用看着使用招的HTTP流量时是成功的调用成功功能。 我想这是因为我的web服务将返回原始JSON而不是JSONP。

我怎么能生产JSONP从这样一个标准的.NET Web服务上的方法响应:

[WebMethod(), ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public Project GetData(int projectID)
{
    Project p = new Project();
    p.Name = "foobar";
    return p;
}

谢谢。

Answer 1:

好了,我终于理解了它自己。 因为我发现这样很难在网上找到一个完整的工作方案,我决定在这里记录我的工作解决方案。

一个JSONP响应仅仅是标准的JSON字符串包裹在一个函数调用。 ASP.NET似乎并没有提供任何办法返回这个格式直接效应初探,但它是非常简单的做这自己。 你这样做虽然要重写JSON编码的默认方法。

下面是JSONP的一个例子。

functionName({ name: 'value';});

..now此位: { name: 'value';}仅仅是标准的JSON,任何JSON序列会给你,所以我们需要做的是对函数调用包装粘性。 不幸的是,这样做意味着我们必须“无线化”(或旁路)现有的JSON这是当你从web服务的函数返回一个对象的框架透明地处理编码。

这是完全通过写JSONP使用我们自己的代码的输出流(响应)覆盖从Web服务功能的响应来完成。 这其实很简单,我已经包括下面的例子。

您可以使用内置的DataContractJsonSerializer (从System.Runtime.Serialization.Json命名空间中的ASP.NET 3.5 +)或NewtonSoft JSON序列化,并且这两个例子如下所示。 我喜欢使用的NewtonSoft JSON (从安装的NuGet),而不是内置的JSON序列化,因为我觉得它给你更多的控制,也可以输出格式良好的调试人类可读的JSON。 这也是在纸上快很多!

[WebMethod()]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public void GetData(int projectID, string callback)
{
    List<Video> videos = null;
    // <code here to populate list on line above>

    // Method 1: use built-in serializer:
    StringBuilder sb = new StringBuilder();
    JavaScriptSerializer js = new JavaScriptSerializer();
    sb.Append(callback + "(");
    sb.Append(js.Serialize(videos));
    sb.Append(");");    

    // Method 2: NewtonSoft JSON serializer (delete as applicable)
    // StringBuilder sb = new StringBuilder();
    // sb.Append(callback + "(");
    // sb.Append(JsonConvert.SerializeObject(videos, Formatting.Indented)); // indentation is just for ease of reading while testing
    // sb.Append(");");     

    Context.Response.Clear();
    Context.Response.ContentType = "application/json";
    Context.Response.Write(sb.ToString());
    Context.Response.End();
}

该方法然后可以使用以下的JQuery代码调用:

$.ajax({
    crossDomain: true,
    contentType: "application/json; charset=utf-8",
    url: "http://examplewebsite.com/service.asmx/GetData",
    data: { projectID: 1 }, // example of parameter being passed
    dataType: "jsonp",
    success: onDataReceived
});

function onDataReceived(data)
{
    alert("Data received");
    // Do your client side work here.
    // 'data' is an object containing the data sent from the web service 
    // Put a JS breakpoint on this line to explore the data object
}


Answer 2:

感谢尼克,这是一个很好的答案,我也有一个很难找到的第一个网上的问题。 工作对我来说相当好。

希望确保这这条线后得到了应有的重视。

只是想补充一点,我使用的内置串行器(System.Runtime.Serialization.Json)和它的工作就像一个魅力也是如此。

        List<orderHistory> orderHistory = null;

        StringBuilder sb = new StringBuilder();
        JavaScriptSerializer js = new JavaScriptSerializer();
        sb.Append(callback + "(");
        sb.Append(js.Serialize(orderHistory));
        sb.Append(");");

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.Write(sb.ToString());
        Context.Response.End();


Answer 3:

万一有人找样本如何返回JSONPASP.NET Web API的行动:

// GET api/values
public JsonpResult Get()
{
    var values = new string[] { "value1", "value2" };
    return new JsonpResult(values);
}

JsonpResult辅助类封装JSONP包装。

public class JsonpResult : JsonResult
{
    object _data = null;

    public JsonpResult(object data)
    {
        _data = data;
    }

    public override void ExecuteResult(ControllerContext controllerContext)
    {
        if (controllerContext != null)
        {
            var response = controllerContext.HttpContext.Response;
            var request = controllerContext.HttpContext.Request;

            var callBackFunction = request["callback"];
            if (string.IsNullOrEmpty(callBackFunction))
            {
                throw new Exception("Callback function name must be provided in the request!");
            }
            response.ContentType = "application/x-javascript";
            if (_data != null)
            {
                var serializer = new JavaScriptSerializer();
                response.Write(string.Format("{0}({1});", callBackFunction, serializer.Serialize(_data)));
            }
        }
    }
}


文章来源: How can I produce JSONP from an ASP.NET web service for cross-domain calls?