通过扩展让ASP.NET Web API支持JSONP ----- .NET 4.0 asp.net WebApi(不是WebApi 2)

来源:互联网 发布:纸质书情怀 知乎 编辑:程序博客网 时间:2024/05/18 03:55

问题背景:

注:下文中 ”webapi“ 和 “webapi” 和“webapi 2”的概念是不一样的,共有3个概念。

前者指asp.net平台中的一种项目框架,

第二个webapi指的其实是“webapi 1”,即.NET 4.0下的webapi框架,

webapi 2指的其实是“webapi 2”,即.NET 4.5+下的webapi框架。


现在我用的(准确来说是我司用的)是.NET 4.0平台,也就是说只能用“webapi 1”而不能用“webapi 2”(不要问我为什么),这样的话就有了新的问题。


既然用到webapi项目,那么跨域显然是难以避免的了,比如 aaa.test.com 向 webapi.test.com发请求,然后得到返回信息。

这就是跨域。

跨域的解决方案也很明显了,每个web开发者都跑不掉的。

1. 同源策略配置解决

2. jsonp方案。


------------------------------

以下是答案。

同源策略方案:

同源策略的配置就是在webapi.test.com站点的web.config文件中配置如下内容 <system.webServer>节点中:

   <httpProtocol>      <customHeaders>        <add name="Access-Control-Allow-Origin" value="*" />        <add name="Access-Control-Expose-Headers" value="key" />        <add name="Access-Control-Allow-Headers" value="Content-Type" />        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />      </customHeaders>    </httpProtocol>

然后跨域请求就可以成功了。

但是问题也有,就是兼容性差。老版IE好像都不行,IE678.


jsonp方案:

问题是webapi(此处指webapi1,webapi 2中怎样,暂未具体了解)中,没有返回jsonp的形式。

如果需要返回jsonp,则需要我们对webapi的http请求的返回信息进行扩展。

搜索webapi jsonp,能搜到很多东西。

比如 蒋金楠大神的 http://www.cnblogs.com/artech/archive/2013/12/05/3460544.html

这里面详细讲了如何扩展webapi使之能够返回jsonp形式的内容。


但是使用webapi的我们,直接将代码复制过来,却是报错的 。

因为.NET 4.0中是不支持这种写法的。

如图中红框处。


其他地方都一切正常。

因此,我们不得不对此处进行改写,其实也就是一个异步的写法而已。

C#的异步写法经过了几次进化,新的写法不支持,那么旧的写法总是可以的。因此这个问题是肯定可以解决的。

改写如下:


代码如下:

    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)        {            if (string.IsNullOrEmpty(this.Callback))            {                return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);            }            try            {                return Task.Factory.StartNew(() =>                {                    this.WriteToStream(type, value, writeStream, content);                });            }            catch (Exception exception)            {                TaskCompletionSource<AsyncVoid> source = new TaskCompletionSource<AsyncVoid>();                source.SetException(exception);                return source.Task;            }        }

其余一切照常,据初步测试来看,好像没有什么问题。

当然别忘了$.ajax()的参数中加入   dataType: "jsonp", 。


0 0