• 当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>

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Python-OpenCV——进阶操作一网打尽
    深入理解jQuery插件开发
    Bootstrap整合ASP.NET MVC验证、jquery.validate.unobtrusive
    实用的Bootstrap的扩展和插件集合
    hadoop编程小技巧(5)---自定义输入文件格式类InputFormat
    mapreduce作业状态一直是ACCEPTED
    hadoop CLASSNAME命令使用注意点
    运行java的class文件方法详解
    Hadoop、Zookeeper、Hbase分布式安装教程
    java enum(枚举)使用详解 + 总结
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1595783.html
Copyright © 2020-2023  润新知