2011-11-10 9 views
19

Ho un'applicazione funzionante che utilizza Json.NET (newtonsoft) come serializzatore personalizzato. Attualmente sto aggiungendo questo derivato di WebHttpBehavior in un WebServiceHostFactory personalizzato. Vedi lo snippet di codice alla fine di this blog per come l'ho allegato.Custom Behavior non si registrerà nel mio web.config

Poiché sto ospitando questo servizio in IIS, vorrei liberarmi del mio codice di hosting personalizzato e aggiungere semplicemente il comportamento personalizzato al mio web.config. La procedura è mostrata in questo msdn article.

così cerco di farlo in questo modo:

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

Purtroppo, io sono in grado di fare quel lavoro. Quando lo faccio, Visual Studio mi dice che

L'elemento 'comportamento' ha valida elemento figlio 'NewtonsoftJsonBehavior'

Nel afforementioned msdn article, si dice che

Per aggiungere capacità di configurazione dell'elemento, è necessario scrivere e registrare un elemento di configurazione. Per ulteriori informazioni, consultare la documentazione System.Configuration.

Dopo aver definito l'elemento e il tipo di configurazione, è possibile utilizzare l'estensione, come mostrato nell'esempio seguente.

Ho la sensazione che quello che mi manca è esattamente questo. In qualche modo registrando l'elemento e il suo tipo di configurazione. Purtroppo non posso creare teste o code dello System.Configuration che dovrebbe dirmi come fare questo. Quindi questa è fondamentalmente la mia domanda:

Come scrivere e registrare l'elemento di configurazione e, se questo non è il mio problema, qual è il problema?

Molte grazie in anticipo!

risposta

37

Il pezzo mancante è la classe BehaviorExtensionElement. Nell'OP stavo tentando di aggiungere la derivata WebHttpBehavior come elemento. BehaviorExtensionElement indica al parser di configurazione quale tipo utilizzare per un determinato elemento.

Ecco l'implementazione di cui avevo bisogno:

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

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

questo non è stato sufficiente a liberarmi del mio WebServiceHostFactory personalizzato, naturalmente.Per ho anche dovuto aggiungere un ContentTypeMapper personalizzato:

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

ho potuto poi usarli nel mio web.config. Ecco le parti rilevanti della configurazione di lavoro. In primo luogo la creazione l'estensione e la configurazione di un comportamento con esso:

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

Poi la configurazione di un webHttpBinding con la mia contentTypeMapper personalizzato:

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

infine la creazione di un endpoint utilizzando il sopra:

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

Spero che questa roba aiuti qualcuno là fuori. :)

2

Se apri questa app.config con svcconfigeditor, dovrebbe iniziare a chiedere di selezionare l'assembly associato a NewtonsoftJsonBehavior. Se lo selezioni e salva ancora l'app.config, questo risolve il tuo problema?

BTW, utilizziamo anche un'estensione di binding personalizzata nelle nostre configurazioni di servizio. L'xml nella configurazione sottolinea sempre l'estensione con un'onda blu che indica che l'elemento non è noto allo schema come lo descrivi. Tuttavia, quando iniziamo il servizio, sia il servizio che il comportamento funzionano come previsto.

+0

Proverò il svcconfigeditor per prima cosa domani e riferirò. Per quanto riguarda l'altra parte, quando provo a eseguire la mia app, la chiamata al servizio mostra il mio web.config nel browser ed evidenzia il tag personalizzato come la ragione per cui il servizio non può essere eseguito. Non riesco a ricordare il messaggio esatto, ma posso postare anche domani, se ciò sarà di aiuto. – Mithon

+0

Aggiungo una mia risposta, ma ho aumentato la tua da quando mi ha indicato SvcConfigEditor mi ha aiutato a rintracciare ciò che dovevo fare. – Mithon