Распространенное исключение 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 или в проекте модульного тестирования с помощью этого кода:

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>

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

**

Updated: I've added comments for more of my troubleshooting on this problem. When an answer is available, if the answer is unpublished, I'll add it as an official "answer".

**

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
30 007
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

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

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

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

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

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

Ответ принят как подходящий

Я нашел ответ

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

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

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

Из всех случайных исключений, которые кто-то мог выдать, это САМОЕ ЛУЧШЕЕ, что могла придумать команда WCF? Я столкнулся с той же проблемой, и я потратил вечность, пытаясь понять, и, чтобы сделать это еще более раздражающим, он работал на моей тестовой машине, но не работал должным образом при перемещении на сервер. IIS - это зло.

thaBadDawg 13.07.2009 20:58

хорошо отвечать на свой вопрос: meta.stackexchange.com/questions/17463/… - думаю, для этого должен быть значок! :)

russau 27.03.2012 03:08

Я думал, что этот ответ был немного случайным. Но полностью раскрыл мой случай!

E-A 12.05.2014 17:24

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

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

public enum Priority
{    
  Low,    
  Medium,    
  High
}

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

Иногда эта ошибка может вводить в заблуждение. Распространенное исключение 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);

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

Верно. Вы можете вернуть IEnumerable <T> и уйти с ленивым вычислением, но если вы вернете тип, который имеет экземпляр IEnumrable <T>, тогда вам лучше вызвать ToList () или иначе. Итак, yield 1; выход 2; выход 3; будет работать, но новый TopLevelObject {Values ​​= некоторая ленивая вычисляемая последовательность} поможет вам.

A-Dubb 19.09.2012 06:54

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

<dataContractSerializer maxItemsInObjectGraph = "2147483647" />

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

<dataContractSerializer maxItemsInObjectGraph = "2147483647" />

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

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

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

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

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

ваше здоровье

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

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

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

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

Другие вопросы по теме