Подтвердить что ты не робот

Общее исключение WCF: соединение неожиданно закрыто

У меня есть три проекта. Один из них - проект служб 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 или в проекте Unit Test с этим кодом:

var client = new TaskManagementClient();

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

client.Close();

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

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

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

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

**

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

**

4b9b3361

Ответ 1

Я нашел ответ

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

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

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

Ответ 2

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

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

public enum Priority
{    
  Low,    
  Medium,    
  High
}

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

Ответ 3

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

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

Ответ 4

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

Ответ 5

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

Ответ 7

В моем случае мой контракт с данными имел свойство [datamember], у которого не было установленного метода. Я использовал трассировку WCF для получения реальной ошибки. fooobar.com/questions/28415/.... Надеюсь, это поможет кому-то.

Ответ 8

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

У меня есть пример статьи, делающей что-то основное, но я использую net.tcp(с безопасностью, установленной как "Нет" ) здесь: Дуплексные службы WCF Хостинг в IIS с использованием Net.Tcp

Кроме того, где вы получаете ошибку... это в строке ".Close()" или в строке ".GetTasks(). ToString()?

Еще одна вещь, которую вы можете проверить, - просто подключить telnet к localhost на порте 9999, чтобы узнать, слушает ли служба для подключения соединений вообще.

Ответ 9

Иногда эта ошибка может быть очень ошибочной. Общее исключение 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);

Ответ 10

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

Ответ 11

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

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

Ответ 12

Кто-то из этой темы добавил, что добавление этого элемента в поведение конечной точки устранило проблему.

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

Это сработало, но его нужно было добавить не только к поведению конечной точки, но и к поведению службы (что имеет смысл, так как именно здесь будет происходить сериализация).

Если он был добавлен в службу только, я получил эту ошибку: "Максимальное количество элементов, которые могут быть сериализованы или десериализованы в графе объектов, равно" 65536 ". Измените граф объекта или увеличьте квоту MaxItemsInObjectGraph."

Если добавлено только к конечной точке, я все еще получил неожиданно закрытую ошибку соединения.