当wcf遇到JSON ?

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

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

ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
InBlock.gif
/// 测试
InBlock.gif
/// </summary>
ExpandedBlockEnd.gif
/// <returns></returns>

None.gif [OperationContract]
None.gif[WebInvoke(Method 
=   " GET " , ResponseFormat  =  WebMessageFormat.Json)]
None.gif
public   string  Test()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return "Hello World!";
ExpandedBlockEnd.gif}

 

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

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

前端用jQuery调用

None.gif < script type = " text/javascript " >
ExpandedBlockStart.gifContractedBlock.gif    $.getJSON(
" /wcf/service.svc/Test " function (data)  dot.gif {
InBlock.gif        alert(data.d.toString());
ExpandedBlockEnd.gif    }
)
None.gif
< / script>

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

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

 

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

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

于是检查web.config

None.gif   < behaviors >
None.gif    
< endpointBehaviors >
None.gif    
< behavior  name ="V6.WebApp.wcf.ServiceAspNetAjaxBehavior" >
None.gif      
< enableWebScript />      
None.gif    
</ behavior >
None.gif    
</ endpointBehaviors >
None.gif
</ 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这种原始格式自己实现,这样不管配置如何,都能保证统一的输出,如下:

ExpandedBlockStart.gif ContractedBlock.gif   /**/ /// <summary>
InBlock.gif
/// 辅助方法,用于输出流
InBlock.gif
/// </summary>
InBlock.gif
/// <param name="str"></param>
ExpandedBlockEnd.gif
/// <returns></returns>

None.gif private  Stream GetStream( string  str)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    MemoryStream ms 
= new MemoryStream();
InBlock.gif    StreamWriter sw 
= new StreamWriter(ms);
InBlock.gif    sw.AutoFlush 
= true;
InBlock.gif    sw.Write(str);
InBlock.gif    ms.Position 
= 0;
InBlock.gif    WebOperationContext.Current.OutgoingResponse.ContentType 
= "text/plain";
InBlock.gif    
return ms;
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /// <summary>
InBlock.gif
/// 测试
InBlock.gif
/// </summary>
ExpandedBlockEnd.gif
/// <returns></returns>

None.gif [OperationContract]
None.gif[WebInvoke(Method 
=   " GET " , ResponseFormat  =  WebMessageFormat.Json,UriTemplate = " HelloWorld " )]
None.gif
public  Stream Test()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return GetStream("{'data':'Hello World!'}");
ExpandedBlockEnd.gif}

None.gif

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值