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

У меня есть рабочее приложение, использующее 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 говорит мне, что

Элемент 'поведение' имеет недопустимый дочерний элемент 'NewtonsoftJsonBehavior'

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

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

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

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

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

Спасибо заранее!

2 ответа

Решение

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

Вот реализация, в которой я нуждался:

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>

Надеюсь, что это поможет кому-то там.:)

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

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

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