Общее исключение WCF: соединение неожиданно закрыто - PullRequest
12 голосов
/ 24 октября 2008

У меня три проекта. Один из них - это проект служб WCF, другой - проект WPF, а другой - проект модульного тестирования Microsoft. Я настроил проект служб WCF с объектом данных, который выглядит следующим образом:

[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; }
}

Мой контракт выглядит так:

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

    [OperationContract]
    void CreateTask(Task taskToCreate);

    [OperationContract]
    void UpdateTask(Task taskToCreate);

    [OperationContract]
    void DeleteTask(Task taskToDelete);
}

Когда я пытаюсь использовать службу в приложении WPF или модульном тестовом проекте с этим кодом:

var client = new TaskManagementClient();

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

client.Close();

Я получаю следующую ошибку: «Базовое соединение было закрыто: соединение было неожиданно закрыто».

Файл app.config для проектов WPF и модульного тестирования выглядит следующим образом:

<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>

и web.config службы WCF выглядит следующим образом:

    <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>

Это не первый раз, когда это происходит, и я предполагаю, что это проблема конфигурации. Но каждый раз я обычно просто сдувал свой сервис и возвращал его обратно или создавал новый сервисный проект. Тогда все работает чудесно. Если у кого-то есть идеи, это было бы здорово. Thx.

**

Обновлено: я добавил комментарии для более моего устранения неполадок по этой проблеме. Когда ответ доступен, если ответ не опубликован, я добавлю его как официальный «ответ».

**

Ответы [ 12 ]

20 голосов
/ 24 октября 2008

Я нашел ответ

Хорошо, не уверен, что Кьюл отвечает на мой собственный вопрос, но здесь мы идем. По какой-то причине перечисление нужно было пометить с помощью атрибутов [EnumMember], как показано ниже:

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

Как только я это сделал, мои тесты и сервисы могли быть вызваны без возникновения ошибки. Я до сих пор не уверен, почему эта конкретная ошибка была отображена. Кажется, ошибка не согласуется ни с какой функциональной причиной, по которой произошла ошибка, но это исправление определенно сгладило все.

7 голосов
/ 07 января 2009

Как вы сами отметили, если вы пометите перечисление как DataContract, вам также придется пометить элементы.

В качестве альтернативы вы можете просто удалить [DataContract] перед вашим перечислением следующим образом:

public enum Priority
{    
  Low,    
  Medium,    
  High
}

Это также сработает, потому что в этом случае WCF обрабатывает перечисление самостоятельно. Если вы пометите его как [DataContract], вы должны пометить каждый элемент так, как вы это заметили.

6 голосов
/ 19 октября 2011

Я получал эту ошибку при возврате большой полезной нагрузки. Оказалось, что DataContractSerialiser останавливает средний поток, поскольку он достиг значения по умолчанию maxItemsInObjectGraph, добавление фоллинга к моему поведению конечной точки устранило проблему

<dataContractSerializer maxItemsInObjectGraph="2147483647" />
3 голосов
/ 23 августа 2011

Я заметил это при использовании LINQ и вызовов типа Select, Where и т. Д. Без немедленного вызова .ToList () или ToArray (). Итераторы доставят вам неприятности. Это не нативные типы, с которыми WCF знает, как работать, например List, Array и т. Д. Они имеют тип WhereEnumerable или что-то в этом роде. Просто имейте это в виду при отправке результатов из NHibernate или Entity Framework. Надеюсь, это кому-нибудь поможет. Мне потребовались часы, чтобы понять.

3 голосов
/ 24 октября 2008

Убедитесь, что ничто, кроме FaultException, не было выброшено и передано обратно клиенту.

2 голосов
/ 06 сентября 2013

В моем случае мой контракт с данными имел свойство [datamember], у которого не было метода set. Я использовал трассировку WCF, чтобы получить реальную ошибку. https://stackoverflow.com/a/4271528/463425. Надеюсь, это кому-нибудь поможет.

2 голосов
/ 12 апреля 2012

Если кто-то еще делает это, я возвращаю список объектов, сгенерированных linq, в файл sql / dbml. Мне просто нужно было включить сериализацию в файле dbml:

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

ура

1 голос
/ 18 декабря 2012

в моем случае я возвращал объект пользовательского класса, одним из членов которого была таблица данных. и если у вас нет имени в таблице данных, он выдаст эту ошибку.

Dim oTable As DataTable = New DataTable 'this wont serialize
Dim oTable As DataTable = New DataTable("MyTable")  'this will serialize
1 голос
/ 18 сентября 2012

Другая причина: это исключение возникает, если у вас есть DataContract/DataMember атрибуты на Interface вместо конкретного типа ( ужасная идея , не делайте этого), и вы пытаетесь сериализовать Concrete type.

1 голос
/ 07 апреля 2010

Иногда эта ошибка может быть очень обманчивой. Распространенное исключение WCF: Соединение неожиданно закрывается, может произойти, если культура настроена неправильно или также в форматировании строки.

Следующие ошибки:

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

пока это работает:

CultureInfo culture = new CultureInfo(this.aculture.Name);               
Convert.ToString(new DateTime(adate.Year, adate.Month, firstday), culture);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...