Domanda

Ho una serie di servizi WCF web collegati dinamicamente da una applicazione desktop.

Il mio problema è la configurazione dettagliata impostazioni che WCF richiede di lavorare.Ottenere SSL per il lavoro comporta impostazioni personalizzate.Ottenere MTOM o qualsiasi altra cosa il lavoro richiede di più.Si desidera che la compressione?Eccoci di nuovo qui...

WCF è davvero potente, si può utilizzare una miriade di modi diversi per collegare, ma tutti sembrano coinvolgere un sacco di configurazione dettagliata.Se l'host e il client non corrispondono perfettamente a ottenere difficile da decifrare errori.

Voglio fare l'app desktop molto più facile da configurare - idealmente alcune specie di auto-scoperta.Gli utenti di desktop app dovrebbe solo essere in grado di inserire l'URL e fare il resto.

Qualcuno sa un buon modo per fare questo?

So che Visual Studio è possibile impostare la config per voi, ma io voglio il desktop app, per essere in grado di farlo sulla base di un'ampia varietà di diversi server di set-up.

So che VS strumenti possono essere utilizzati anche all'esterno, ma sto cercando per gli utenti delle applicazioni del desktop di non essere WCF esperti.So di MS fatta intenzionalmente più complicato.

C'è un modo, il meccanismo, la 3 ° festa della libreria o nulla a che fare auto-scoperta di WCF impostazioni possibili?

È stato utile?

Soluzione

Tutte le informazioni sull'endpoint è disponibile nei metadati di un servizio, è possibile scrivere un client che esplorerà i meta dati del servizio e configurare il client.Per un esempio di codice che si può guardare in questo eccellente Mex Explorer da Juval Lowy.

Altri suggerimenti

Grazie, era codice utile (+1).

E 'più di un po' disordinato, però, ha alcuni bug (maiuscole e minuscole) controlla che non dovrebbe essere, per esempio), ha un carico di funzionalità dell'interfaccia utente, che non ho bisogno e ripete un sacco di codice.

Ho preso da lui il reale meccanismo di individuazione, ri-scritto e quasi capito di lavoro (si connette, ma ha bisogno di qualche finessing).

Prima un po ' di util funzioni utilizzate dal metodo main:

/// <summary>If the url doesn't end with a WSDL query string append it</summary>
static string AddWsdlQueryStringIfMissing( string input )
{
    return input.EndsWith( "?wsdl", StringComparison.OrdinalIgnoreCase ) ?
        input : input + "?wsdl";
}

/// <summary>Imports the meta data from the specified location</summary>
static ServiceEndpointCollection GetEndpoints( BindingElement bindingElement, Uri address, MetadataExchangeClientMode mode )
{
    CustomBinding binding = new CustomBinding( bindingElement );
    MetadataSet metadata = new MetadataExchangeClient( binding ).GetMetadata( address, mode );
    return new WsdlImporter( metadata ).ImportAllEndpoints();
}

Quindi un metodo che cerca un modo diverso per collegare e restituisce l'endpoint:

public static ServiceEndpointCollection Discover( string url )
{
    Uri address = new Uri( url );
    ServiceEndpointCollection endpoints = null;

    if ( string.Equals( address.Scheme, "http", StringComparison.OrdinalIgnoreCase ) )
    {
        var httpBindingElement = new HttpTransportBindingElement();

        //Try the HTTP MEX Endpoint
        try { endpoints = GetEndpoints( httpBindingElement, address, MetadataExchangeClientMode.MetadataExchange ); }
        catch { }

        //Try over HTTP-GET
        if ( endpoints == null )
            endpoints = GetEndpoints( httpBindingElement,
                new Uri( AddWsdlQueryStringIfMissing( url ) ), MetadataExchangeClientMode.HttpGet );
    }
    else if ( string.Equals( address.Scheme, "https", StringComparison.OrdinalIgnoreCase ) )
    {
        var httpsBindingElement = new HttpsTransportBindingElement();

        //Try the HTTPS MEX Endpoint
        try { endpoints = GetEndpoints( httpsBindingElement, address, MetadataExchangeClientMode.MetadataExchange ); }
        catch { }

        //Try over HTTP-GET
        if ( endpoints == null )
            endpoints = GetEndpoints( httpsBindingElement,
                new Uri( AddWsdlQueryStringIfMissing( url ) ), MetadataExchangeClientMode.HttpGet );
    }
    else if ( string.Equals( address.Scheme, "net.tcp", StringComparison.OrdinalIgnoreCase ) )
        endpoints = GetEndpoints( new TcpTransportBindingElement(), 
            address, MetadataExchangeClientMode.MetadataExchange );

    else if ( string.Equals( address.Scheme, "net.pipe", StringComparison.OrdinalIgnoreCase ) )
        endpoints = GetEndpoints( new NamedPipeTransportBindingElement(), 
            address, MetadataExchangeClientMode.MetadataExchange );

    return endpoints;
}

Ora c'è un altro modo per farlo che non era disponibile quando ho chiesto la domanda originale.Microsoft supporta ora di RIPOSO per i servizi WCF.

  • Lo svantaggio di usare il RESTO è che si perde il WSDL.
  • Il vantaggio è minimo config e WCF contratto interfacce continuerà a funzionare!

Avrete bisogno di un nuovo punto di riferimento per System.ServiceModel.Web

Mark le operazioni con WebInvoke o WebGet

//get a user - note that this can be cached by IIS and proxies
[WebGet]
User GetUser(string id )

//post changes to a user
[WebInvoke]
void SaveUser(string id, User changes )

L'aggiunta di questi per un sito è facile aggiungere un .svc file:

<%@ServiceHost 
   Service="MyNamespace.MyServiceImplementationClass" 
   Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

La fabbrica dice ASP.net come attivare l'endpoint - non hai bisogno di lato server config a tutti!

Quindi la costruzione di ChannelFactory è praticamente invariato, tranne che non è necessario specificare un endpoint di più (o di auto-scoperta di uno come ho già fatto in altre risposte)

var cf = new WebChannelFactory<IMyContractInterface>();
var binding = new WebHttpBinding();

cf.Endpoint.Binding = binding;
cf.Endpoint.Address = new EndpointAddress(new Uri("mywebsite.com/myservice.svc"));
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());

IMyContractInterface wcfClient = cf.CreateChannel();

var usr = wcfClient.GetUser("demouser");
// and so on...

Notare che non ho specificato o scoperto il client config - non ci sono locali config necessario!

Un altro grande vantaggio è che si può facilmente passare a JSON messa in serie - che consente alla stessa di servizi WCF per essere consumato da Java, ActionScript, Javascript, Silverlight o qualsiasi altra cosa in grado di gestire JSON e di RIPOSO facilmente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top