I am proper struggling getting that "magic" moment when WCF is configured nicely and jQuery is structuring its requests/understanding responses nicely.
当WCF被很好地配置,jQuery很好地构造了它的请求/理解响应时,我正在努力获得“神奇”的时刻。
I have a service:
我有一个服务:
<%@ ServiceHost Language="C#" Debug="true" Service="xxx.yyy.WCF.Data.ClientBroker" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>
This was recommended by the man Rick Strahl to avoid having to define the behaviours within Web.config.
这是Rick Strahl推荐的,以避免在Web.config中定义行为。
My interface for the WCF service sits in another assembly:
我的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);
}
}
The concrete service class is:
具体服务类别为:
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;
}
}
}
My IClient is an Entity Framework class so is decorated with DataContract/DataMember attributes appropriately.
我的IClient是一个实体框架类,因此使用适当的DataContract/DataMember属性。
I am trying to call my WCF service using the methods outlined on Rick Strahl's blog at http://www.west-wind.com/weblog/posts/324917.aspx (the "full fat" version). The debugger jumps into the WCF service fine (so my jQuery/JSON is being understood) and gets the IClient and returns it. However, when I return the response, I get various useless errors. The errors I am getting back don't mean much.
我正在尝试使用Rick Strahl在http://www.west-wind.com/weblog/posts/324917.aspx(“full fat”版本)的博客中列出的方法调用我的WCF服务。调试器会跳转到WCF服务(以便理解我的jQuery/JSON)并获得IClient并返回它。但是,当我返回响应时,会得到各种无用的错误。我所犯的错误并没有多大意义。
I am using POST.
我使用POST。
Am I right to be using an Interface instead of a concrete object? As it does get into the WCF service, it does seem to be the encoding of the result that is failing.
我是否有权使用一个接口而不是一个具体的对象?由于它确实进入了WCF服务,它似乎确实是失败的结果的编码。
Does anyone have any ideas?
有人有什么想法吗?
3 个解决方案
#1
10
At first glance there are three problems with your code:
乍一看,您的代码有三个问题:
1: you should use the ServiceKnownTypeAttribute to specify known types when exposing only base types in your operation contracts:
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: You should use WebMessageBodyStyle.WrappedRequest
instead of WebMessageBodyStyle.Wrapped
because the latter is not compatible with WebScriptServiceHostFactory.
2:你应该使用WebMessageBodyStyle。WrappedRequest代替WebMessageBodyStyle。包装,因为后者与WebScriptServiceHostFactory不兼容。
3: IMHO using Method="GET" would be more RESTful for a method called GetClientJson than Method="POST"
3:使用Method="GET"的IMHO比方法="POST"更符合rest风格
Another advice I could give you when working with WCF services is to use SvcTraceViewer.exe bundled with Visual Studio. It is a great tool for debugging purposes. All you need is to add the following section to your app/web.config:
在使用WCF服务时,我可以给您的另一个建议是使用SvcTraceViewer。exe与Visual Studio绑定。这是一个很好的调试工具。你只需要在你的app/web.config中添加以下部分:
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "WcfDetailTrace.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
Then invoke the web method and WcfDetailTrace.e2e file will be generated in your web site root directory. Next open this file with SvcTraceViewer.exe and you will see lots of useful information. For example it could say:
然后调用web方法和WcfDetailTrace。e2e文件将在您的web站点根目录中生成。接下来用SvcTraceViewer打开这个文件。你会看到很多有用的信息。例如,它可以说:
Cannot serialize parameter of type 'MyNamespace.Client' (for operation 'GetClientJson', contract 'IClientBroker') because it is not the exact type 'MyNamespace.IClient' in the method signature and is not in the known types collection. In order to serialize the parameter, add the type to the known types collection for the operation using ServiceKnownTypeAttribute.
无法序列化类型“MyNamespace”的参数。客户端(对于操作“GetClientJson”,契约为“IClientBroker”),因为它不是确切的类型“MyNamespace”。IClient'在方法签名中,不在已知类型集合中。为了序列化参数,使用ServiceKnownTypeAttribute将类型添加到操作的已知类型集合中。
Of course you should not forget commenting this section before going into production or you might end up with some pretty big files.
当然,在开始生产之前,您不应该忘记注释这一节,否则您可能会得到一些非常大的文件。
#2
2
I am 99% sure you cant return an interface. I dont think Interfaces are serializable.
我99%肯定你不能返回接口。我不认为接口是可序列化的。
check out this thread
看看这个线程
#3
0
Related to the question, a while ago I posted an article on my blog showing all the steps needed to get a WCF service working together with jQuery code on the client side:
与此相关的是,不久前我在我的博客上发表了一篇文章,展示了让WCF服务与客户端jQuery代码一起工作所需的所有步骤:
http://yoavniran.wordpress.com/2009/08/02/creating-a-webservice-proxy-with-jquery/
http://yoavniran.wordpress.com/2009/08/02/creating-a-webservice-proxy-with-jquery/
#1
10
At first glance there are three problems with your code:
乍一看,您的代码有三个问题:
1: you should use the ServiceKnownTypeAttribute to specify known types when exposing only base types in your operation contracts:
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: You should use WebMessageBodyStyle.WrappedRequest
instead of WebMessageBodyStyle.Wrapped
because the latter is not compatible with WebScriptServiceHostFactory.
2:你应该使用WebMessageBodyStyle。WrappedRequest代替WebMessageBodyStyle。包装,因为后者与WebScriptServiceHostFactory不兼容。
3: IMHO using Method="GET" would be more RESTful for a method called GetClientJson than Method="POST"
3:使用Method="GET"的IMHO比方法="POST"更符合rest风格
Another advice I could give you when working with WCF services is to use SvcTraceViewer.exe bundled with Visual Studio. It is a great tool for debugging purposes. All you need is to add the following section to your app/web.config:
在使用WCF服务时,我可以给您的另一个建议是使用SvcTraceViewer。exe与Visual Studio绑定。这是一个很好的调试工具。你只需要在你的app/web.config中添加以下部分:
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "WcfDetailTrace.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
Then invoke the web method and WcfDetailTrace.e2e file will be generated in your web site root directory. Next open this file with SvcTraceViewer.exe and you will see lots of useful information. For example it could say:
然后调用web方法和WcfDetailTrace。e2e文件将在您的web站点根目录中生成。接下来用SvcTraceViewer打开这个文件。你会看到很多有用的信息。例如,它可以说:
Cannot serialize parameter of type 'MyNamespace.Client' (for operation 'GetClientJson', contract 'IClientBroker') because it is not the exact type 'MyNamespace.IClient' in the method signature and is not in the known types collection. In order to serialize the parameter, add the type to the known types collection for the operation using ServiceKnownTypeAttribute.
无法序列化类型“MyNamespace”的参数。客户端(对于操作“GetClientJson”,契约为“IClientBroker”),因为它不是确切的类型“MyNamespace”。IClient'在方法签名中,不在已知类型集合中。为了序列化参数,使用ServiceKnownTypeAttribute将类型添加到操作的已知类型集合中。
Of course you should not forget commenting this section before going into production or you might end up with some pretty big files.
当然,在开始生产之前,您不应该忘记注释这一节,否则您可能会得到一些非常大的文件。
#2
2
I am 99% sure you cant return an interface. I dont think Interfaces are serializable.
我99%肯定你不能返回接口。我不认为接口是可序列化的。
check out this thread
看看这个线程
#3
0
Related to the question, a while ago I posted an article on my blog showing all the steps needed to get a WCF service working together with jQuery code on the client side:
与此相关的是,不久前我在我的博客上发表了一篇文章,展示了让WCF服务与客户端jQuery代码一起工作所需的所有步骤:
http://yoavniran.wordpress.com/2009/08/02/creating-a-webservice-proxy-with-jquery/
http://yoavniran.wordpress.com/2009/08/02/creating-a-webservice-proxy-with-jquery/