当WCF配置得很好并且jQuery很好地构建其请求/理解响应时,我正在努力获得"神奇"的时刻.
我有一个服务:
<%@ ServiceHost Language="C#" Debug="true" Service="xxx.yyy.WCF.Data.ClientBroker" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>
这是由Rick Strahl建议的,以避免在Web.config中定义行为.
我的WCF服务接口位于另一个程序集中:
namespace xxx.yyy.WCF.Data { [ServiceContract(Namespace = "yyyWCF")] public interface IClientBroker { [OperationContract] [WebInvoke(Method="POST",BodyStyle=WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)] IClient GetClientJson(int clientId); } }
具体的服务类是:
namespace xxx.yyy.WCF.Data { [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] class ClientBroker : IClientBroker { public IClient GetClientJson(int clientId) { IClient client=new Client(); // gets and returns an IClient return client; } } }
我的IClient是一个Entity Framework类,因此适当地使用DataContract/DataMember属性进行修饰.
我试图使用Rick Strahl的博客http://www.west-wind.com/weblog/posts/324917.aspx("全脂版")上列出的方法调用我的WCF服务.调试器很好地跳转到WCF服务(所以我的jQuery/JSON正在被理解)并获取IClient并返回它.但是,当我返回响应时,我会遇到各种无用的错误.我得到的错误并不重要.
我正在使用POST.
我是否正确使用接口而不是具体对象?因为它确实进入了WCF服务,它似乎是失败的结果的编码.
有没有人有任何想法?
乍一看,您的代码有三个问题:
1:在操作合同中仅显示基类型时,应使用ServiceKnownTypeAttribute指定已知类型:
[ServiceContract(Namespace = "yyyWCF")] public interface IClientBroker { [OperationContract] [ServiceKnownType(typeof(Client))] [WebInvoke( Method="GET", BodyStyle=WebMessageBodyStyle.WrappedRequest, ResponseFormat=WebMessageFormat.Json)] IClient GetClientJson(int clientId); }
2:您应该使用WebMessageBodyStyle.WrappedRequest
而不是WebMessageBodyStyle.Wrapped
因为后者与WebScriptServiceHostFactory不兼容.
3:使用Method ="GET"的IMHO对于一个名为GetClientJson的方法比Method ="POST"更加RESTful
使用WCF服务时,我可以给你的另一个建议是使用与Visual Studio捆绑在一起的SvcTraceViewer.exe.它是一个很好的调试工具.您只需将以下部分添加到您的app/web.config:
然后调用Web方法,将在您的网站根目录中生成WcfDetailTrace.e2e文件.接下来使用SvcTraceViewer.exe打开此文件,您将看到许多有用的信息.例如它可以说:
无法序列化'MyNamespace.Client'类型的参数(对于操作'GetClientJson',收缩'IClientBroker'),因为它不是方法签名中的确切类型'MyNamespace.IClient',并且不在已知类型集合中.要序列化参数,请使用ServiceKnownTypeAttribute将类型添加到操作的已知类型集合中.
当然,在开始制作之前你不应该忘记评论这一部分,或者你最终会得到一些相当大的文件.