Пользовательское поведение не регистрируется в моем web.config

#.net #wcf #iis #configuration-files #wcf-behaviour

#.net #wcf #iis #конфигурационные файлы #wcf-поведение

Вопрос:

У меня есть рабочее приложение, использующее Json.NET (newtonsoft) в качестве пользовательского сериализатора. В настоящее время я добавляю эту производную от WebHttpBehavior в пользовательский WebServiceHostFactory. Смотрите фрагмент кода в конце этого блога, чтобы узнать, как я его прикрепил.

Поскольку я размещаю эту службу в IIS, я хотел бы избавиться от своего пользовательского кода хостинга и просто добавить пользовательское поведение в мой web.config. Процедура показана в этой статье msdn.

Поэтому я пытаюсь сделать это следующим образом:

 <behaviors>
  <endpointBehaviors>
    <behavior name="jsonRest">
      <webHttp defaultOutgoingResponseFormat="Json" />
      <NewtonsoftJsonBehavior/>
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add name="NewtonsoftJsonBehavior" type="Newtonsoft.Json.Extensions.NewtonsoftJsonBehavior, NewtonsoftJsonExtensions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>
  

К сожалению, я не могу заставить это работать. Когда я это делаю, Visual Studio сообщает мне, что

Элемент ‘behavior’ имеет недопустимый дочерний элемент ‘NewtonsoftJsonBehavior’

В упомянутой статье msdn говорится, что

Чтобы добавить возможности настройки к элементу, вам необходимо написать и зарегистрировать элемент конфигурации. Дополнительную информацию об этом см. в Системе.Документация по конфигурации.

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

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

Как мне написать и зарегистрировать элемент конфигурации, и если это не моя проблема, то в чем проблема?

Заранее большое спасибо!

Ответ №1:

Недостающая часть — это класс BehaviorExtensionElement. В OP я пытался добавить производную WebHttpBehavior в качестве элемента. BehaviorExtensionElement сообщает анализатору конфигурации, какой тип использовать для определенного элемента.

Вот реализация, которая мне была нужна:

 public class NewtonsoftJsonBehaviorExtension : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get { return typeof(NewtonsoftJsonBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new NewtonsoftJsonBehavior();
    }
}
  

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

 public class NewtonsoftJsonContentTypeMapper : WebContentTypeMapper
{
    public override WebContentFormat GetMessageFormatForContentType(string contentType)
    {
        return WebContentFormat.Raw;
    }
}
  

Затем я мог бы использовать их в своем Web.config. Вот соответствующие части рабочей конфигурации. Сначала настраиваем расширение и настраиваем поведение с его помощью:

 <extensions>
  <behaviorExtensions>
    <add name="newtonsoftJsonBehavior" type="Newtonsoft.Json.Extensions.NewtonsoftJsonBehaviorExtension, NewtonsoftJsonExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>
<behaviors>
  <endpointBehaviors>
    <behavior name="jsonRestEndpointBehavior">
      <webHttp/>
      <newtonsoftJsonBehavior/>
    </behavior>
  </endpointBehaviors>
<behaviors>
  

Затем настройка webHttpBinding с помощью моего пользовательского contentTypeMapper:

 <bindings>
  <webHttpBinding>
    <binding name="newtonsoftJsonBinding" contentTypeMapper="Newtonsoft.Json.Extensions.NewtonsoftJsonContentTypeMapper, NewtonsoftJsonExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </webHttpBinding>
</bindings>
  

Наконец, настройка конечной точки с использованием вышеуказанного:

 <services>
  <service name="My.Namespaced.MyService" behaviorConfiguration="jsonRestServiceBehavior">
    <endpoint address=""                behaviorConfiguration="jsonRestEndpointBehavior"
              binding="webHttpBinding"  bindingConfiguration="newtonsoftJsonBinding" 
              contract="My.Namespaced.IMyService" />
  </service>
</services>
  

Надеюсь, что этот материал кому-нибудь поможет. 🙂

Ответ №2:

Если вы откроете это приложение.config с помощью svcconfigeditor, оно должно начать запрашивать выбор сборки, связанной с NewtonsoftJsonBehavior. Если вы выберете это и снова сохраните app.config, решит ли это вашу проблему?

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

Комментарии:

1. Завтра я первым делом попробую svcconfigeditor и сообщу об этом. Что касается другой части, когда я пытаюсь запустить свое приложение, вызов службы показывает мой web.config в браузере и выделяет пользовательский тег как причину, по которой служба не может запуститься. Не могу вспомнить точное сообщение, но могу опубликовать и завтра, если это поможет.

2. Добавил свой собственный ответ, но поддержал ваш, поскольку указание мне на SvcConfigEditor помогло мне отследить, что мне нужно было сделать.