2011-11-10 16 views
19

Tengo una aplicación en funcionamiento que usa Json.NET (newtonsoft) como un serializador personalizado. Actualmente estoy agregando esta derivada de WebHttpBehavior en un WebServiceHostFactory personalizado. Consulte el fragmento de código al final de this blog para ver cómo lo he adjuntado.Comportamiento personalizado no se registrará en mi web.config

Como estoy alojando este servicio en IIS, me gustaría deshacerme de mi código de hosting personalizado y simplemente agregar el comportamiento personalizado a mi web.config. El procedimiento se muestra en este msdn article.

así que trato de hacerlo de esta manera:

<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> 

Lamentablemente, no soy capaz de hacer ese trabajo. Cuando hago eso, Visual Studio me dice que

El elemento 'comportamiento' tiene inválida elemento hijo 'NewtonsoftJsonBehavior'

En el afforementioned msdn article, se dice que

Para añadir habilidades de configuración para el elemento, necesita escribir y registrar un elemento de configuración. Para obtener más información al respecto, consulte la documentación System.Configuration.

Después de definir el elemento y su tipo de configuración, se puede usar la extensión, como se muestra en el siguiente ejemplo.

Tengo la sensación de que lo que me estoy perdiendo es exactamente eso. De alguna manera, registrando el elemento y su tipo de configuración. Lamentablemente, no puedo dar con la cara o el rabo del System.Configuration que se supone que me dice cómo hacerlo. Esa es básicamente mi pregunta:

¿Cómo escribo y registro el elemento de configuración, y si ese no es mi problema, cuál es el problema?

¡Muchas gracias de antemano!

Respuesta

37

La pieza que falta es la clase BehaviorExtensionElement. En el PO, estaba intentando agregar WebHttpBehavior-derivative como un elemento. El BehaviorExtensionElement le dice al configurador-analizador qué Tipo debe usar para un determinado elemento.

Ésta es la aplicación que necesitaba:

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

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

esto no fue suficiente para deshacerse de mi WebServiceHostFactory costumbre, por supuesto.Porque también yo tenía que añadir un ContentTypeMapper personalizado:

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

pude luego usarlos en mi Web.config. Aquí están las partes relevantes de la configuración de trabajo. En primer lugar la creación de la extensión y configuración de un comportamiento con ella:

<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> 

A continuación, la configuración de un webHttpBinding con mi costumbre contentTypeMapper:

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

Por último la creación de un punto final utilizando la anterior:

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

Espero que esto ayude a alguien por ahí. :)

2

Si abre este app.config con svcconfigeditor, debería comenzar solicitando seleccionar el ensamblado asociado con el NewtonsoftJsonBehavior. Si seleccionas eso y guardas el app.config nuevamente, ¿eso resuelve tu problema?

BTW, también utilizamos una extensión de enlace personalizado en nuestras configuraciones de servicio. El xml en la configuración siempre subraya la extensión con una onda azul que indica que el elemento no se conoce en el esquema tal como lo describe. Sin embargo, cuando comenzamos el servicio, tanto el servicio como el comportamiento funcionan como se espera.

+0

Voy a probar el svcconfigeditor mañana a primera hora e informaré de nuevo. En cuanto a la otra parte, cuando intento ejecutar mi aplicación, llamar al servicio muestra mi web.config en el navegador y resalta la etiqueta personalizada como la razón por la cual el servicio no se puede ejecutar. No recuerdo el mensaje exacto, pero también puedo publicarlo mañana, si eso ayuda. – Mithon

+0

Agregué una respuesta por mi cuenta, pero voté por encima suyo ya que al señalarme el SvcConfigEditor me ayudó a encontrar lo que tenía que hacer. – Mithon

Cuestiones relacionadas