Почему не найден мой пользовательский тип элемента расширения поведения WCF?
У меня есть решение, которое содержит два проекта. Один проект - это проект веб-приложения ASP.NET, а другой - библиотека классов. У веб-приложения есть проектная ссылка на библиотеку классов. Ни один из них не является строго названным.
В библиотеке классов, которую я назову "Framework", у меня есть поведение конечной точки (реализация IEndpointBehavior) и элемент конфигурации (класс, производный от BehaviorExtensionsElement). Элемент конфигурации таков, что я могу присоединить поведение конечной точки к сервису через конфигурацию.
В веб-приложении у меня есть служба WCF с поддержкой AJAX. В файле web.config у меня есть служба AJAX, настроенная для использования моего собственного поведения. Раздел system.serviceModel конфигурации довольно стандартный и выглядит следующим образом:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyEndpointBehavior">
<enableWebScript />
<customEndpointBehavior />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="WebSite.AjaxService">
<endpoint
address=""
behaviorConfiguration="MyEndpointBehavior"
binding="webHttpBinding"
contract="WebSite.AjaxService" />
</service>
</services>
<extensions>
<behaviorExtensions>
<add
name="customEndpointBehavior"
type="Framework.MyBehaviorExtensionsElement, Framework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
Во время выполнения это работает отлично. Служба WCF с поддержкой AJAX правильно использует мое настроенное поведение конечной точки.
Проблема в том, когда я пытаюсь добавить новую службу AJAX WCF. Если я добавлю -> Новый элемент... и выберу "Службу WCF с поддержкой AJAX", я смогу посмотреть, как он добавляет файл.svc и код, но когда происходит обновление файла web.config, я получаю эту ошибку:
Файл конфигурации не является допустимым файлом конфигурации для библиотеки служб WCF.
Не удалось загрузить тип Framework.MyBehaviorExtensionsElement, Framework, Version=1.0.0.0, Culture= нейтральный, PublicKeyToken=null, зарегистрированный для расширения "customEndpointBehavior".
Очевидно, что конфигурация полностью действительна, так как она отлично работает во время выполнения. Если я временно удаляю элемент из своей конфигурации поведения, а затем добавляю службу WCF с поддержкой AJAX, все проходит без проблем.
К сожалению, в более крупном проекте, где у нас будет несколько сервисов с различными конфигурациями, временное удаление всех пользовательских поведений будет подвержено ошибкам. Хотя я понимаю, что могу обойтись без мастера и делать все вручную, не каждый может, и было бы неплохо иметь возможность использовать продукт в том виде, в котором он предназначен - мастера и все такое.
Почему не найден мой пользовательский тип элемента расширения поведения WCF?
Обновления / разъяснения:
- Он работает во время выполнения, но не во время разработки.
- Сборка Framework находится в папке bin веб-проекта, когда я пытаюсь добавить службу.
- Хотя я мог бы добавлять службы вручную ("без конфигурации"), мне нужен готовый шаблон элемента для работы - вот и вся цель вопроса.
- Эта проблема видна в Visual Studio 2008. В VS 2010 эта проблема, похоже, решена.
Я подал эту проблему в Microsoft Connect, и оказалось, что вы должны либо поместить свой пользовательский элемент конфигурации в GAC, либо поместить его в папку IDE. Они не будут это исправлять, по крайней мере пока. Я разместил обходной путь, который они предоставили как "ответ" на этот вопрос.
11 ответов
В соответствии с обходным решением, которое Microsoft опубликовала для проблемы Connect, которую я подал для этого, это известная проблема, и не будет никакого решения для нее, по крайней мере в текущем выпуске:
Причина сбоя при добавлении нового элемента службы: при добавлении нового элемента и обновлении файла конфигурации система попытается загрузить файл конфигурации, поэтому она попытается найти и загрузить сборку расширения cusom в этом файле конфигурации. Только в тех случаях, когда сборка GACed или находится по тому же пути, что и exe (Program Files\Microsoft Visual Studio 9.0\Common7\IDE), система может найти ее. В противном случае появится диалоговое окно с сообщением об ошибке и "добавить новый элемент" не удастся.
Я понимаю ваши болевые точки. К сожалению, мы не можем принять это изменение в текущем выпуске. Мы рассмотрим его в более поздних выпусках и постараемся предложить лучшее решение, такое как предоставление диалогового окна просмотра, позволяющего клиентам указывать путь, или более качественное сообщение об ошибке, указывающее на какое-то решение вокруг, и т. Д.
Можете ли вы попробовать обойти на текущем этапе: GAC свою собственную сборку расширения или скопировать его в "Program Files\Microsoft Visual Studio 9.0\Common7\IDE"?
Мы предоставим файл readme, чтобы помочь другим клиентам, которые могут столкнуться с той же проблемой.
К сожалению, похоже, мне не повезло в этом.
В качестве FYI для любого, кто сталкивается с этим в наши дни, возможное решение - ПОЛНОСТЬЮ квалифицировать вашу сборку в вашем app.config/web.config. Например, если бы вы имели
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="clientCredential" type="Client.ClientCredentialElement, Client" />
</behaviorExtensions>
</extensions>
попробуйте - заменить значения как необходимые
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="clientCredential" type="Client.ClientCredentialElement, Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
это конкретное решение сработало для меня.
Я просто использовал
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyVersion("1.0.0.0")]
//[assembly: AssemblyFileVersion("1.0.0.0")]
Поэтому каждый раз у меня новый номер сборки сборки.
Но у нас есть
<add name="clientCredential" type="Client.ClientCredentialElement, Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
где Версия =1.0.0.0 ЭТО НЕПРАВИЛЬНО!!!
Итак, у вас есть 2 варианта
Вернуться к
//[assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] Keep it manually. [assembly: AssemblyFileVersion("1.0.0.0")]
Каждая сборка вручную заменяет версию =1.0.0.0 на правильный номер.
Я попробовал это с новым проектом, просто чтобы убедиться, что это не ваш конкретный проект / конфиг и что у меня точно такая же проблема.
При использовании журналов слияния создается впечатление, что система ищет расширения поведения ТОЛЬКО в каталоге IDE (C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE). Копирование сборки в этот каталог на этапе после сборки работает, но выглядит ужасно.
Вот список шагов, сработавших для меня:
- Установите DLL в GAC, т.е. gacutil /i Bla.dll
- Получите FQN из dll, т.е. gacutil /l Bla
- Скопируйте полученный FQN в Web.config
- Добавить новый сервис в VS
- Удалите dll из GAC, т.е. gacutil /u Bla
Все вместе только.
У вас есть копия Framework.dll с вашим пользовательским поведением в каталоге bin вашего веб-проекта? Если нет, то это, вероятно, проблема. Visual Studio ищет реализацию поведения. Так как он указан в вашей конфигурации, он не думает искать в других проектах; он ожидает найти сборку в мусорном ведре.
В зависимости от того, как настроен ваш проект, он может запускаться в режиме отладки без помещения этой сборки в корзину, хотя VS обычно собирает ее и помещает туда. Но опять же, это зависит от того, как все настроено.
В любом случае, возможно, стоит просто проверить еще раз, что сборка доступна во время разработки.
Поместить сборку в GAC, вероятно, поможет, но я ценю, что это не тот ответ, который вы ищете. Не уверен, где еще VS будет искать сборки, кроме GAC и каталога, содержащего devenv.exe.
У меня был класс расширения в том же проекте (dll), что и мой класс обслуживания, и я не смог заставить его работать. Однажды я переместил его в другой проект и сослался на него из сервисного проекта, он работал. На всякий случай, если кто-то еще столкнется с этой проблемой.
Я решил эту проблему, закомментировав соответствующие разделы в web.config, включая элемент, который использовал пользовательское расширение, элемент и элемент.
После этого я смог добавить службу WCF в проект, добавить строки обратно в web.config и опубликовать проект.
В моем классе был определен класс расширения, реализующий мой интерфейс, что привело к ошибке «не удалось загрузить», когда WCF не смог загрузить мой класс расширения.
Перемещение определения класса расширения из реализации интерфейса (но все еще в том же проекте /dll) решило мою проблему.
Если вы используете фреймворк 3.5, культура = нейтральный в малом, а не культура = нейтральный в капитале