当wcf遇到JSON ?

昨天在调试项目时,意外发现一个奇怪的问题,实在不知道如何准确描述,所以随便起了个标题。

项目中有一个wcf供jquery调用,wcf示例代码如下:

/**//// <summary>
/// 测试
/// </summary>
/// <returns></returns>
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
public string Test()
{
    return "Hello World!";
}

简单得不能再简单了,返回一个json格式的Hello World!

在非IE浏览器里用 http://localhost/wcf/service.svc/Test/ 测试(因为IE7以上版本好象不能直接打开访问wcf中的办法,会提示禁止访问,所以只能用ff,chrome之类测试),返回的是{"d":"Hello World!"},完全正常!(这里的d:是微软自动为我们的数据加的一层壳)

前端用jQuery调用

<script type="text/javascript">
    $.getJSON("/wcf/service.svc/Test", function(data) {
        alert(data.d.toString());
    })
</script>

弹出"Hello World!"一切都很理想 后来因为项目需要,有人觉得Test这个名称太土,想换个名字,而程序员又不乐意,于是用UriTemplate起了个别名HelloWorld应付,如下:

/**//// <summary>
/// 测试
/// </summary>
/// <returns></returns>
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,UriTemplate="HelloWorld")]
public string Test()
{
    return "Hello World!";
}

浏览器里用http://localhost/wcf/service.svc/HelloWorld 测试,报错如下:

使用“UriTemplate”的终结点无法用于“System.ServiceModel.Description.WebScriptEnablingBehavior”。

于是检查web.config

<behaviors>
    <endpointBehaviors>
    <behavior name="V6.WebApp.wcf.ServiceAspNetAjaxBehavior">
      <enableWebScript/>     
    </behavior>
    </endpointBehaviors>
</behaviors>

把 <enableWebScript/>换成<webHttp/>,解决!

这时发现麻烦才刚开始,这里发现http://localhost/wcf/service.svc/HelloWorld返回的数据格式变成了"Hello World!",没有刚才的那一层套套(即d:),所以前端用alert(data.d.toString())当然会报错了,真不明白微软为啥要搞出这样标准不统一的JSON封装? 知道了问题所在,解决办法自然也明了:

1.要么把老老实实把Test方法名,换成HelloWorld 2.要么把前端alert(data.d.toString())改成alert(data.toString())

最终建议:

尽量还是不要采用wcf默认的json封装,可以用Stream这种原始格式自己实现,这样不管配置如何,都能保证统一的输出,如下:

/**//// <summary>
/// 辅助方法,用于输出流
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private Stream GetStream(string str)
{
    MemoryStream ms = new MemoryStream();
    StreamWriter sw = new StreamWriter(ms);
    sw.AutoFlush = true;
    sw.Write(str);
    ms.Position = 0;
    WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
    return ms;
}

/**//// <summary>
/// 测试
/// </summary>
/// <returns></returns>
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,UriTemplate="HelloWorld")]
public Stream Test()
{
    return GetStream("{'data':'Hello World!'}");
}

前端

<script type="text/javascript">
$.getJSON("/wcf/service.svc/HelloWorld", function(a) {           
    alert(a.data.toString());
})
</script>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏zhisheng

Windows 64位下安装Redis超详细教程

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(...

437120
来自专栏闵开慧

java获取cpu、内存、硬盘信息

1 下载安装sigar-1.6.4.zip     使用java自带的包获取系统数据,容易找不到包,尤其是内存信息不够准确,所以选择使用sigar获取系统信息。...

89790
来自专栏Java开发者杂谈

JDK1.7新特性(3):java语言动态性之脚本语言API

简要描述:其实在jdk1.6中就引入了支持脚本语言的API。这使得java能够很轻松的调用其他脚本语言。具体API的使用参考下面的代码: 1 package...

311100
来自专栏Java技术分享圈

杨老师课堂之JavaSe 部分面试题

​ JVM 是 JavaVirtual Machine 的缩写,全称是 Java 虚拟机。Java 语言的一个非常重要的 特性就是跨平台性,而 Java 虚...

10830
来自专栏python3

python3--模块collections,time,random,sys

有如下值集合[11,22,33,44,55,66,77,88,99,90......],将所有大于66的值保存至字典的第一个key中,小于66的值保存至第二个k...

10920
来自专栏皮皮之路

【JVM】浅谈双亲委派和破坏双亲委派

笔者曾经阅读过周志明的《深入理解Java虚拟机》这本书,阅读完后自以为对jvm有了一定的了解,然而当真正碰到问题的时候,才发现自己读的有多粗糙,也体会到只有实践...

32920
来自专栏北京马哥教育

一篇文章学会shell工具篇之sed

? sed工具执行原理; 有关sed的参数及action的常见操作方法; 定址; 模式空间和保持空间; 使用标签 1.首先先来了解一下什么是sed? sed叫...

33270
来自专栏无题

堆外内存概要

DirectByteBuffer JDK中使用 DirectByteBuffer对象来表示堆外内存,每个 DirectByteBuffer对象在初始化时,都会创...

25740
来自专栏大内老A

[WCF REST] WebHttpBinding与消息编码

不论是我们采用SOAP还是REST架构风格,运行时框架体系依然不曾改变,终结点也仍旧是通信的核心。在Web HTTP编程模型中,我们采用基于WebHttpBin...

22160
来自专栏加米谷大数据

Python 3.7.0 正式版新特性解析

美国时间6月27日晚8点,Python 3.7.0 经过多轮测试,终于发布了正式版,增强了多处特性功能,同时 3.6 也更新到 3.6.6 稳定版本。

18910

扫码关注云+社区

领取腾讯云代金券