Пространство имен справочной службы WCF отличается от исходного

StackOverflow https://stackoverflow.com/questions/1200346

Вопрос

У меня проблема с пространством имен, используемым ссылками на мои службы. У меня есть несколько служб WCF, скажем, с пространством имен MyCompany.Services.MyProduct ( фактические пространства имен длиннее ).
В рамках этого продукта я также предоставляю пример веб-сайта на C # .NET. Это веб-приложение использует пространство имен MyCompany.MyProduct.

Во время первоначальной разработки сервис был добавлен в качестве ссылки на сайт проекта и используется напрямую. Я использовал фабричный шаблон, который возвращает экземпляр объекта, который реализует MyCompany.Services.MyProduct.IMyService. Пока все хорошо.

Теперь я хочу изменить это, чтобы использовать реальную ссылку на сервис. После добавления ссылки и ввода using в текстовом поле пространства имен он создает классы в пространстве имен MyCompany.MyProduct.MyCompany.Services.MyProduct . ПЛОХО! Мне не нужно менять директивы global:: в нескольких местах только потому, что я использую прокси-класс. Поэтому я попытался добавить пространство имен к MyCompany, но это не принято.

Обратите внимание, что я еще даже не удалил исходные ссылки на сборки, и " повторно используйте типы " включен, но повторное использование не было выполнено, по-видимому. Однако я не хочу хранить ссылки на сборки на моем образце веб-сайта, чтобы он все равно работал .

Единственное решение, которое я до сих пор предлагал, - это установить для пространства имен по умолчанию для моего веб-приложения значение Services.MyProduct (поскольку оно не может быть пустым) и добавить ссылку на службу как OtherCompany.Whatever. Предположим, что клиент хочет использовать мой пример веб-сайта в качестве отправной точки, и они изменяют пространство имен по умолчанию на <=>, это, очевидно, сломает мой обходной путь.

Есть ли хорошее решение этой проблемы?

Подводя итог : я хочу создать ссылочный прокси-сервер службы в исходном пространстве имен без ссылки на сборку.

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

<Ч>

Редактировать. Как предположил Джон Сондерс, я отправил Microsoft свой отзыв об этом:
Элемент обратной связи @ Microsoft Connect

Это было полезно?

Решение

Я добавил write- этого решения в мой блог. На самом деле та же информация, но, возможно, чуть менее фрагментированная

Я нашел альтернативу использованию svcutil.exe для достижения желаемого. Это (imo) делает обновление ссылки на службу проще, чем повторный запуск утилиты.

Вы должны явно указать uri пространства имен в своих ServiceContract и DataContracts ( см. ниже комментарий для ).

[ServiceContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public interface IService
{
    [OperationContract]
    CompositeType GetData();
}

[DataContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public class CompositeType
{
    // Whatever
}

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

После этого включите параметр Показать все файлы в обозревателе решений. Разверните ссылку на услугу, которую вы добавили ранее. Дважды щелкните файл Reference.svcmap.

Там будет элемент <NamespaceMappings />, который вам нужно будет отредактировать. Продолжая мой пример:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="http://company.com/MyCompany.Services.MyProduct"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>

Сохраните файл, нажмите правой кнопкой мыши ссылку на службу и выберите Обновить справку службы .

Вы можете добавить столько сопоставлений, сколько вам нужно (мне фактически понадобилось два). Эффект такой же, как и в подходе svcutil /namespace:, но без использования самого утилиты командной строки, что упрощает обновление.

Разница с svcutil

Недостатком этого подхода является то, что вам нужно использовать явные отображения пространства имен. Используя svcutil, у вас есть возможность отобразить все, что не отображено явно, как это (решение, на которое ссылался Джон Сондерс):

svcutil /namespace:*,MyCompany.Services.MyProduct ...

Вы можете подумать об использовании:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="*"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>

но это не будет работать, потому что Visual Studio уже неявно добавляет это отображение, указывая на сгенерированное имя пространства имен, от которого мы пытаемся избавиться. Приведенная выше конфигурация приведет к тому, что Visual Studio будет жаловаться на дубликат ключа.

Явные пространства имен объявлений :
Если в вашем коде не указано пространство имен explit, кажется , что .NET сгенерирует URI в форме http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct . Вы можете отобразить это так же, как и явные пространства имен в моем примере, но я не знаю, есть ли какая-либо гарантия для такого поведения. Поэтому лучше использовать явное пространство имен.

Примечание: сопоставление двух пространств TargetNamespace с одним и тем же пространством ClrNamespace, по-видимому, нарушает генерацию кода

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

Ваш вариант использования был неверным.

Во-первых, вы никогда не должны были включать службу в качестве ссылки.

Я полагаю, что svcutil.exe примет параметр, указывающий полное пространство имен для использования.

В VS2010 и более поздних версиях есть способ настроить пользовательские пространства имен. В обозревателе решений выберите & Quot; Показать все файлы & Quot; затем откройте " веб-ссылки " в дереве решений выберите сервис, выберите узел Reference.map, отобразите свойства и установите свойство пространства имен пользовательского инструмента.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top