Почему WCF не распознает атрибут DataContract класса, когда пространство имен ServiceContract указано в отдельном интерфейсе? - PullRequest
0 голосов
/ 05 октября 2019

У нас есть служба WCF, которая недавно переместила все операции на асинхронные. Мы внедрили это с новым контрактом на обслуживание, чтобы охватить эти операции, но как ServiceContract Name, так и OperationContract Names нового контракта указывают на старые ServiceContract и OperationContract Names для обеспечения обратной совместимости.

Примерно так:

[ServiceContract(Namespace= "", Name = nameof(IOldContract))]
public interface INewAsyncContract
{
    [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
    [OperationContract(Name = nameof(IOldContract.DoThing))]
    Task<DoThingResponse> DoThingAsync(DoThingRequest doThingRequest);
}

В то время как старый контракт выглядит следующим образом:

[ServiceContract]
public interface IOldContract
{
    [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
    [OperationContract]
    DoThingResponse DoThing(DoThingRequest doThingRequest);
}

Примечание. В старом контракте на обслуживание отсутствует значение пространства имен. Это верно в кодовой базе.

Теперь к вопросу: когда мы внедряем эту службу с пространством имен ServiceContract в новом контракте на обслуживание, мы получаем эту ошибку при переходе к службе:

ExceptionDetail, вероятно, созданный IncludeExceptionDetailInFaults = true, значение которого: System.InvalidOperationException: было сгенерировано исключение при вызове расширения экспорта WSDL: System.ServiceModel.Description.DataContractSerializerOperationBehavior contract: IOldContract ---->System.Xml.Schema.XmlSchemaException: глобальный элемент 'DoThingResponse' уже объявлен.

И наоборот, если мы публикуем без пространства имен, служба работает как положено, но предоставляется пространство имен по умолчанию. (http://tempuri.org),, который нам не нужен.

Почему пространство имен ServiceContract мешает отклонению DoThingResponse?

Изменить, чтобы добавить определение DoThingResponse:

[DataContract(Namespace = "")]
public class DoThingResponse
{
    [DataMember]
    public obj ResponseObj { get; set; }
}

1 Ответ

1 голос
/ 08 октября 2019

Похоже, мы неоднократно объявляли DoThingResponse. Я хотел бы знать, как вы определяете пользовательский класс и структуру проекта.
Атрибут пространства имен и атрибута имени контракта на обслуживание применяются к документу метаданных, предоставляемому сервисом (документ WSDL). Атрибут пространства имен используется в качестве пространства имен элемента porttype в документе WSDL. Значение по умолчанию - http://tempuri.org.
Атрибут name применяет имя элемента porttype в документе WSDL. Эти значения являются уникальными и не могут быть повторены.
Уникальные значения используются для маркировки элементов в конверте в конверте SOAP.
Не стесняйтесь, дайте мне знать, если есть что-то, с чем я могу помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...