J'ai passé quelques heures à rechercher cette erreur et à tester presque tout ce qui se trouve sur Google.
Je souhaite accéder à un service utilisant TCP, .NET4 et VS2010, en C #.
J'ai un tout petit service:
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);
}
}
}
Avec ce 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>
Et ce code pour l'héberger:
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();
}
}
Maintenant, je veux créer le client, mais ce n'est pas possible. J'ai utilisé Add Service Reference et svcutil directement, mais je reçois cette erreur:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC> svcutil.exe net.tcp: // loc alhost: 5050/Service1 Modèle de service Microsoft (R) Outil de métadonnées [Microsoft (Windows) Windows (R) Communication Foundation, Version 4.0.30319.1] Copyright (c) Microsoft Corporation. Tous les droits réservé.
Tentative de téléchargement de métadonnées à partir de 'net.tcp: // localhost: 5050/Service1' à l'aide de W S-Metadata Exchange. Ce L'URL ne supporte pas DISCO. Outil de métadonnées de modèle de service Microsoft (R) [Fondation de communication Microsoft (R) Windows (R), version 4.0.30319.1] Copyright (c) Microsoft Corporation. Tous les droits sont réservés.
Erreur: Impossible d'obtenir les métadonnées de net.tcp: // localhost: 5050/Service1
S'il s'agit d'un service Windows (R) Communication Foundation auquel vous avez accès acce ss, vérifiez que vous avez activé la publication des métadonnées à l'adresse spécifiée. Pour obtenir de l'aide sur la publication de métadonnées, veuillez vous reporter à la documentation MSDN à l'adresse http://go.Microsoft.com/fwlink/?LinkId=65455 .
Erreur d’échange WS-Metadata URI: net.tcp: // localhost: 5050/Service1
Les métadonnées contiennent une référence qui ne peut pas être résolue: 'net.tcp: // localhost: 5050/Service1'.
La connexion de socket a été interrompue. Cela pourrait être dû à une erreur de traitement de votre message ou à un dépassement du délai de réception de l'hôte distant, ou un problème de ressource réseau non dérivé. Local le délai d'attente de la prise était '00: 04: 59.9863281 '.
Si vous souhaitez l'interaction d'un hôte existant par l'hôte remoto
Si vous souhaitez plus d’aide, tapez "svcutil /?"
Donc, je peux héberger le service sans problèmes mais je ne peux pas créer les procurations.
J'ai essayé presque toutes les configurations que j'ai trouvées, mais je pense que le fichier web.config actuel est correct. Il y a les comportements, la sécurité et les liaisons utilisant mex, utilisées par les points finaux.
J'ai essayé de créer un fichier app.config et de le définir dans le même dossier que svcutil.exe.
Il manque la configuration du service
<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>
Avec cette configuration, vous n'avez pas besoin de définir l'adresse de base dans le code.
J'ai reçu la même erreur en tentant de mettre à jour une référence de service existante. Il se trouve que j'avais des contrats de données portant le même nom dans le même espace de noms. Une enquête plus poussée a révélé la véritable erreur:
DataContract pour le type [expurgé] ne peut pas être ajouté à DataContractSet car le type ' [expurgé] ' avec le même nom de contrat de données 'DocumentInfo' dans l'espace de noms ' [expurgé] ' est déjà présent et les contrats ne sont pas équivalents.
J'ai changé le DataContract pour donner un nom à l'une des classes.
[DataContract(Namespace = "urn:*[redacted]*:DataContracts", Name = "SC_DocumentInfo")]
Je poste ceci ici au cas où cela pourrait aider quelqu'un avec le même problème.
Je recevais le même message d'erreur et il s'est avéré que le problème était dû au texte dans un bloc de commentaires
<!-- comments included characters like à, ç and ã -->
Après avoir supprimé ces caractères du bloc commenté, tout fonctionne bien
Peut-être que ce sera utile pour quelqu'un.
Mon problème était lié à un argument contractuel et je l'ai découvert à l'aide de Event Viewer:
L'opération [Nom de la méthode] a un paramètre ou un type de retour attribué avec MessageContractAttribute. Afin de représenter le message de requête à l'aide d'un contrat de message, l'opération doit avoir un paramètre unique attribué avec MessageContractAttribute. Afin de représenter le message de réponse à l'aide d'un contrat de message, la valeur de retour de l'opération doit être un type attribué à MessageContractAttribute et l'opération peut ne comporter aucun paramètre out ou ref.
Donc, si vous avez ajouté plus d'un argument et que vous avez déjà l'argument [MessageContract], vous verrez une erreur en question. Complètement pas évident.
J'ai eu le même problème (lorsque le client n'a pas "vu" le service dans le menu "Ajouter une référence de service") en utilisant uniquement la liaison TCP. Après avoir essayé d'ajouter Behavior, mon service devait se terminer par une exception, car il ne trouvait pas l'adresse correcte. Je ne sais pas si c'est la meilleure idée, mais vous pouvez ajouter une deuxième adresse de base en tant que http .... voici ma configuration et mon code, cela fonctionne.
<?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>
Et le code
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();
L'adresse http est maintenant utilisée par le client pour ajouter une référence de service, et la configuration générée automatiquement côté client utilise le protocole net.tcp pour appeler la fonction.
Pour le problème ci-dessus, vérifiez le fichier reference.svc généré au moment où vous ajoutez la référence. L'URL mentionné dans qui sera utilisé pour mettre à jour le service afin que vous puissiez vérifier si cela fonctionne ou non.