Question

J'ai trois projets. L'un est un projet de services WCF, un autre projet WPF et un autre projet de tests unitaires Microsoft. J'ai configuré le projet de services WCF avec un objet de données ressemblant à ceci:

[DataContract]
public enum Priority
{
    Low,
    Medium,
    High
}

[DataContract]
public struct TimeInfo
{
    [DataMember]
    public Int16 EstimatedHours { get; set; }

    [DataMember]
    public Int16 ActualHours { get; set; }

    [DataMember]
    public DateTime StartDate { get; set; }

    [DataMember]
    public DateTime EndDate { get; set; }

    [DataMember]
    public DateTime CompletionDate { get; set; }
}

[DataContract]
public class Task
{
    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public Priority Priority { get; set; }

    [DataMember]
    public TimeInfo TimeInformation { get; set; }

    [DataMember]
    public Decimal Cost { get; set; }
}

Mon contrat ressemble à ceci:

[ServiceContract]
public interface ITaskManagement
{
    [OperationContract]
    List<Task> GetTasks();

    [OperationContract]
    void CreateTask(Task taskToCreate);

    [OperationContract]
    void UpdateTask(Task taskToCreate);

    [OperationContract]
    void DeleteTask(Task taskToDelete);
}

Lorsque j'essaie d'utiliser le service dans l'application WPF ou le projet de test d'unité avec ce code:

var client = new TaskManagementClient();

textBox1.Text = client.GetTasks().ToString();

client.Close();

Le message d'erreur suivant s'affiche: "La connexion sous-jacente a été fermée: la connexion a été fermée de manière inattendue."

Le fichier app.config des projets WPF et de tests unitaires se présente comme suit:

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_ITaskManagement" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" establishSecurityContext="true" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:9999/TaskManagement.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITaskManagement"
            contract="TaskManagement.ITaskManagement" name="WSHttpBinding_ITaskManagement">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

et la configuration web du service WCF se présente comme suit:

    <system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="InternetBasedWcfServices.TaskManagementBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="InternetBasedWcfServices.ScheduleManagementBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service behaviorConfiguration="InternetBasedWcfServices.TaskManagementBehavior"
            name="InternetBasedWcfServices.TaskManagement">
            <endpoint address="" binding="wsHttpBinding" contract="InternetBasedWcfServices.ITaskManagement">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
        <service behaviorConfiguration="InternetBasedWcfServices.ScheduleManagementBehavior"
            name="InternetBasedWcfServices.ScheduleManagement">
            <endpoint address="" binding="wsHttpBinding" contract="InternetBasedWcfServices.IScheduleManagement">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
</system.serviceModel>

Ce n’est pas la première fois que cela se produit, et j’imagine que c’est un problème de configuration. Mais à chaque fois, je viens d’engloutir mon service et de le remettre en place ou de créer un nouveau projet de service. Ensuite, tout fonctionne à merveille. Si quelqu'un a des idées, ce serait génial. Thx.

**

  

Mise à jour: j'ai ajouté des commentaires à plus de   de mon dépannage sur ce problème.   Lorsqu'une réponse est disponible, si le   réponse est non publiée, je vais l'ajouter comme   une "réponse" officielle.

**

Était-ce utile?

La solution

J'ai trouvé la réponse

D'accord, je ne sais pas s'il répond correctement à ma propre question, mais voilà. Pour une raison quelconque, l'énumération devait être marquée avec les attributs [EnumMember] comme ci-dessous:

[DataContract]
public enum Priority
{
    [EnumMember]
    Low,
    [EnumMember]
    Medium,
    [EnumMember]
    High
}

Une fois que j'ai fait cela, mes tests et services pourraient être appelés sans que l'erreur ne se produise. Je ne sais toujours pas pourquoi cette erreur spécifique a été affichée. L’erreur ne semble pas correspondre à la raison fonctionnelle de l’erreur, mais ce correctif a définitivement réglé le problème.

Autres conseils

Comme vous l'avez vous-même noté, si vous indiquez que l'énumération est DataContract, vous devez également marquer les éléments.

Comme alternative, vous pouvez simplement supprimer le [DataContract] avant votre enum comme ceci:

public enum Priority
{    
  Low,    
  Medium,    
  High
}

Cela fonctionnerait également car dans ce cas, WCF gère l’énumération par elle-même. Si vous le marquez comme [DataContract], vous devez marquer chaque élément comme vous l’avez remarqué vous-même.

Je recevais cette erreur en renvoyant une charge utile importante. Il s’est avéré que le flux de données DataContractSerialiser s’arrêtait comme il était entré dans le paramètre par défaut maxItemsInObjectGraph, en ajoutant le comportement suivant à mon point de terminaison qui a résolu le problème

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

Assurez-vous qu'aucun élément qui n'est pas une exception FaultException n'est renvoyé et transmis au client.

Je l’ai remarqué lors de l’utilisation de LINQ et d’appels tels que Select, Where, etc. sans appel immédiat à .ToList () ou ToArray (). Les itérateurs vous attireront des ennuis. Ce ne sont pas des types natifs avec lesquels WCF sait travailler, tels que List, Array, etc. Ils sont du type WhereEnumerable ou quelque chose du genre. N'oubliez pas cela lorsque vous renvoyez les résultats de NHibernate ou Entity Framework. J'espère que ça aide quelqu'un. Il m'a fallu des heures pour comprendre.

Si quelqu'un d'autre le fait également, je renvoie une liste d'objets générés par linq dans un fichier sql / dbml. Je viens juste d'activer la sérialisation dans le fichier dbml:

http://blogs.msdn.com/b/wriju/archive/2007/11/27/linq-to-sql-enabling-dbml-file-for-wcf.aspx

acclamations

Dans mon cas, mon contrat de données avait une propriété [datamember] qui ne comportait pas de méthode set. J'ai utilisé une trace WCF pour obtenir la véritable erreur. https://stackoverflow.com/a/4271528/463425 . J'espère que cela aide quelqu'un.

Je pourrais être loin, mais ça pourrait être un problème de sécurité ... J'ai déjà eu cette erreur, et je l'ai résolue ... mais j'ai passé des jours à essayer de résoudre de nombreux bugs .

J'ai un exemple d'article qui fait quelque chose de fondamental, mais j'utilise net.tcp (avec la sécurité définie sur "Aucun") ici: Services Duplex WCF hébergés dans IIS à l'aide de Net.Tcp

En outre, où obtenez-vous l'erreur ... est-ce sur le champ ".Close ()"? ligne, ou le ".GetTasks (). ToString ()" ligne?

Une autre chose que vous pouvez vérifier est de simplement connecter telnet à localhost sur le port 9999 pour voir si le service écoute complètement les connexions entrantes.

Parfois, cette erreur peut être très trompeuse. Exception WCF commune: connexion inopinément fermée peut se produire lorsque la culture n’est pas définie correctement ou lors du formatage de chaîne.

La suite échoue:

new DateTime(adate.Year, adate.Month, firstday).ToString("d", cultureInfo);

pendant que cela fonctionne:

CultureInfo culture = new CultureInfo(this.aculture.Name);               
Convert.ToString(new DateTime(adate.Year, adate.Month, firstday), culture);

Une autre raison: cette exception survient si vous avez des attributs DataContract / DataMember sur une interface au lieu d'un type concret ( idée terrible , ne le fais pas) et vous êtes essayer de sérialiser le type concret .

dans mon cas, je renvoyais un objet de classe personnalisé, dont l'un des membres était une table de données. et si vous n'avez pas de nom sur le datatable, cette erreur sera renvoyée.

Dim oTable As DataTable = New DataTable 'this wont serialize
Dim oTable As DataTable = New DataTable("MyTable")  'this will serialize

Quelqu'un sur ce fil a posté que l'ajout de cet élément au comportement du terminal a résolu le problème.

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

Cela a fonctionné, mais il a fallu l'ajouter non seulement au comportement du terminal client, mais également au comportement du service (ce qui est logique puisque c'est là que la sérialisation aura lieu).

S'il a été ajouté uniquement au service, l'erreur suivante apparaît: "Le nombre maximal d'éléments pouvant être sérialisés ou désérialisés dans un graphe d'objets est '65536'. Modifiez le graphique d'objet ou augmentez le quota MaxItemsInObjectGraph. "

Si ajouté uniquement au système d'extrémité, l'erreur de connexion inopinément fermée est toujours survenue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top