我花了几个小时来搜索这个错误,我几乎测试了它在Google上的所有内容。
我想在C#中使用TCP,.NET4和VS2010访问服务。
我有一个非常小的服务:
namespace WcfService_using_callbacks_via_tcp
{
[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
public interface IService1
{
[OperationContract]
string Test(int value);
}
public interface ICallback
{
[OperationContract(IsOneWay = true)]
void ServerToClient(string sms);
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1 : IService1
{
public string Test(int value)
{
ICallback the_callback = OperationContext.Current.GetCallbackChannel<ICallback>();
the_callback.ServerToClient("Callback from server, waiting 1s to return value.");
Thread.Sleep(1000);
return string.Format("You entered: {0}", value);
}
}
}
使用此Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService_using_callbacks_via_tcp.Service1" behaviorConfiguration="Behaviour_Service1">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:5050/Service1" />
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" bindingConfiguration="DuplexNetTcpBinding_IService1" contract="WcfService_using_callbacks_via_tcp.IService1"/>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="mexTcp" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<!--
TCP Binding
-->
<netTcpBinding>
<binding name="DuplexNetTcpBinding_IService1" sendTimeout="00:00:01"
portSharingEnabled="true">
</binding>
<binding name="mexTcp" portSharingEnabled="true">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<!--
Behaviour to avoid a rush of clients and to expose metadata over tcp
-->
<behavior name="Behaviour_Service1">
<serviceThrottling maxConcurrentSessions="10000"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
这个代码来托管它:
static void Main(string[] args)
{
Uri base_address = new Uri("net.tcp://localhost:5050/Service1");
ServiceHost host = null;
try
{
// Create the server
host = new ServiceHost(typeof(Service1), base_address);
// Start the server
host.Open();
// Notify it
Console.WriteLine("The service is ready at {0}", base_address);
// Allow close the server
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close it
host.Close();
}
catch (Exception ex)
{
// Opus an error occurred
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(string.Format("Host error:\r\n{0}:\r\n{1}", ex.GetType(), ex.Message));
Console.ReadLine();
}finally
{
// Correct memory clean
if(host != null)
((IDisposable)host).Dispose();
}
}
现在我想创建客户端,但我不可能。我直接使用了Add Service Reference和svcutil,但是我收到了这个错误:
C:\ Program Files(x86)\ Microsoft Visual Studio 10.0 \ VC> svcutil.exe net.tcp:// loc alhost:5050 / Service1 Microsoft(R)服务模型元数据工具[Microsoft(R)Windows(R)Communication Foundation ,版本4.0.30319.1]版权所有(c)Microsoft Corporation。版权所有。
尝试使用W S-Metadata Exchange从'net.tcp:// localhost:5050 / Service1'下载元数据。此URL不支持DISCO。 Microsoft(R)服务模型元数据工具[Microsoft(R)Windows(R)Communication Foundation,版本4.0.30319.1]版权所有(c)Microsoft Corporation。版权所有。
错误:无法从net.tcp:// localhost:5050 / Service1获取元数据
如果这是您已加入的Windows(R)Communication Foundation服务,请检查您是否已在指定的地址启用了元数据发布。有关启用元数据发布的帮助,请参阅http://go.microsoft.com/fwlink/?LinkId=65455上的MSDN文档。
WS-Metadata Exchange错误URI:net.tcp:// localhost:5050 / Service1
元数据包含无法解析的引用:'net.tcp:// localhost:5050 / Service1'。
套接字连接已中止。这可能是由于错误处理您的消息或远程主机超出接收超时或未经过网络资源问题引起的。本地套接字超时为'00:04:59.9863281'。
已强制远程主机中断现有连接
如果您需要更多帮助,请输入“svcutil /?”
所以,我可以毫无问题地托管服务,但我无法创建代理。
我已经尝试了几乎任何我发现的配置,但我认为当前的web.config是正确的。使用mex的行为,安全性和绑定由端点使用。
我尝试创建app.config并使用svcutil.exe将其设置为同一文件夹。
您缺少服务配置
<system.serviceModel>
<services>
<service name="WcfService_using_callbacks_via_tcp.Service1"
behaviorConfiguration="Behavior_Service1">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:5050/Service1" />
</baseAddresses>
</host>
<endpoint address="" contract="WcfService_using_callbacks_via_tcp.IService1"
binding="netTcpBinding" bindingConfiguration="DuplexNetTcpBinding_IService1" />
<endpoint address="mex" contract="IMetadataExchange" binding="mexTcpBindng" />
</service>
</services>
...
</system.serviceModel>
使用此配置,您不需要在代码中定义基址。
尝试更新现有服务引用时收到了同样的错误。事实证明,我在同一名称空间中拥有相同名称的数据协定。进一步的调查产生了真正的错误:
类型[编辑]的DataContract无法添加到DataContractSet,因为类型'[编辑]'在命名空间'[编辑]'中具有相同的数据协定名称'DocumentInfo'已经存在且合同不相等。
我更改了DataContract以为其中一个类提供名称。
[DataContract(Namespace = "urn:*[redacted]*:DataContracts", Name = "SC_DocumentInfo")]
我在这里发布这个,以防它可能帮助有同样问题的人。
我得到了相同的错误消息,事实证明,问题是由于注释块中的文本
<!-- comments included characters like à, ç and ã -->
从注释块中删除这些字符后,一切正常
我遇到了同样的问题(当客户端没有“看到”“添加服务引用”菜单中的服务时),而只使用tcp绑定。尝试添加行为后,我让我的服务以异常结束,因为它没有找到正确的地址。我不知道这是不是最好的主意,但你可以添加第二个基地址为http ....这里是我的配置和代码,它的工作原理。
<?xml version="1.0" encoding="utf-8" ?><configuration> <system.serviceModel> <services>
<service name="TestBindings.StockQuoteService">
<host>
<baseAddresses>
<add baseAddress="net.tcp://10.62.60.62:34000/StockQuoteService" />
<add baseAddress ="http://10.62.60.62:12000/StockQuoteService"/>
</baseAddresses>
</host>
<endpoint address=""
contract="TestBindings.IStockQuoteService"
binding="netTcpBinding" />
</service>
</services>
和代码
class Program
{
static void Main(string[] args)
{
ServiceHost sh = new ServiceHost(typeof(StockQuoteService));
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
sh.Description.Behaviors.Add(behavior);
sh.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(),
"mex");
sh.Open();
http地址现在由客户端用来添加服务引用,客户端自动生成的配置使用net.tcp协议来调用该函数。
也许这对某人有帮助。
我的问题是在合同论证中,我在事件查看器的帮助下发现了它:
操作[方法名称]具有参数或返回类型,该类型与MessageContractAttribute一起归属。为了使用消息协定表示请求消息,该操作必须具有使用MessageContractAttribute归属的单个参数。为了使用消息协定表示响应消息,操作的返回值必须是使用MessageContractAttribute归属的类型,并且操作可能没有任何out或ref参数。
因此,如果您附加了多个参数,已经有[MessageContract]参数,那么您将看到有问题的错误。完全不明显。
对于上述问题,请检查在添加引用时生成的reference.svc文件。其中提到的URL将用于更新服务,以便您可以检查它是否正在运行。