46 messaggi dal 16 gennaio 2009
Per fare pratica ho creato soluzione composta da un progetto ASP.Net Core2.2 MVC e da una WCF Service application allo scopo di vedere se riuscivo a consumare i servizi WCF all'interno dell'app ASP.Net Core.
Ho lasciato l'applicazione WCF service così come me la crea Visual Studio (servizi e relativi contratti) per cercare di semplificare il tutto poichè mi interessa per ora capire a step i meccanismi.
A questo punto ho cercato di aggiungere il riferimento al WCF web service al progetto ma ottengo quanto segue:

Importing web service metadata ...
Number of service endpoints found: 1
Scaffolding service reference code ...
Warning: No endpoints compatible with .Net Core apps were found.
Warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Could not load type 'System.Web.PreApplicationStartMethodAttribute' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='IService1']
Warning: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='IService1']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='BasicHttpBinding_IService1']
Warning: Cannot import wsdl:port
Detail: 
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:service[@name='Service1']/wsdl:port[@name='BasicHttpBinding_IService1']
Error: No code was generated.
If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or services, or because all contracts/services were discovered to exist in --reference assemblies. Verify that you passed all the metadata documents to the tool.
Done.

C'è forse qualche incompatibilità con il Net Core 2.2 come sembra voglia dire il primo warning?

Grazie a chi vorrà aiutarmi a capire.
Modificato da lucios il 31 luglio 2019 15:49 -
49 messaggi dal 20 luglio 2011
hai usato questa procedura https://docs.microsoft.com/it-it/dotnet/core/additional-tools/wcf-web-service-reference-guide ?

"Imparare è un'esperienza, tutto il resto è solo informazione." -Albert Einstein-
46 messaggi dal 16 gennaio 2009
Si, il riquadro postato è il risultato di quella procedura
11.862 messaggi dal 09 febbraio 2002
Contributi
Ciao, hai provato a generare il client con svcutil?
In pratica, apri il prompt dei comandi per sviluppatori di Visual Studio e poi lanci il comando che trovi qui.
https://stackoverflow.com/questions/23997821/how-to-generate-wcf-service-with-svcutil-exe

In questo modo dovresti riuscire a generare le classi client.
Copia nel tuo progetto ASP.NET Core il file .cs che hai ottenuto. Avrai probabilmente degli errori di compilazione su alcuni attributi. Posta qui gli eventuali errori, ma prova anche ad eliminarli perché poi dovrebbe andare.

ciao,
Moreno
Modificato da BrightSoul il 01 agosto 2019 22:30 -

Enjoy learning and just keep making
46 messaggi dal 16 gennaio 2009
Sono riuscito a generare il client con svcutil ed ho ottenuto il file.cs che ho copiato nel progetto ASP Net core sotto la cartella "Connected Services". E' giusto?
Ma svcutil mi ha anche prodotto un file .config. Come lo innesto nel progetto?

Comunque ho provato a richiedere il servizio ma ottengo un errore:

PlatformNotSupportedException: Configuration files are not supported.

System.ServiceModel.ClientBase<TChannel>..ctor()

Quando tento di istanziare la classe client che dovrebbe consumare il servizio.
Modificato da lucios il 08 agosto 2019 17:01 -
11.862 messaggi dal 09 febbraio 2002
Contributi

Ma svcutil mi ha anche prodotto un file .config. Come lo innesto nel progetto?

Non lo innesti. Un client WCF si può configurare anche da codice C#, quindi il file .config non dovrai includerlo nell'applicazione. Però ti servirà per capire come configurare il client da C#, perciò, se puoi postane in contenuto (oscura url o altro eventuale dato sensibile).

Ecco un esempio di come configurare il client da C#. Prendi spunto dal codice che trovi dentro il metodo Run().
https://docs.microsoft.com/it-it/dotnet/framework/wcf/feature-details/how-to-use-the-channelfactory

In questo esempio, il client è stato configurato com un BasicHttpBinding ma nel tuo caso potrebbe essere differente (es. BasicHttpsBinding). Devi capirlo osservando il contenuto del file .config.

ciao,
Moreno

Enjoy learning and just keep making
46 messaggi dal 16 gennaio 2009
C'è qualcosa che non mi torna nella procedura di SCVUTIL.exe.

Provo a riassumere a grandi linee il mio progetto così magari risulta più chiaro.

Ho creato una soluzione comprendente tre progetti:
1 - Progetto in ASP.NET Core 2 dell'applicazione.
2 - Progetto di libreria WCF che dovrebbe fornire i servizi verso l'impianto industriale.
3 - Progetto console che funge da host per il progetto di libreria WCF.

Nella mia testa, ma magari sbaglio, l'app ASP.Net Core dovrebbe usufruire dei servizi di libreria attraverso l'host che deve partire in automatico e che funziona da "anti-corruption layer" a causa dell'utilizzo di librerie COM che non vengono "digerite" dai progetti ASP.NET core.

Però non riesco a capire come generare il client lato ASP.NET che richieda i servizi all'host e non utilizzi direttamente quelli della libreria WCF.

Spero di essere stato sufficientemente chiaro ma non è facile...

Grazie
11.862 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Però non riesco a capire come generare il client lato ASP.NET che richieda i servizi all'host e non utilizzi direttamente quelli della libreria WCF.

Devi compilare e avviare il progetto console, in modo che il servizio e il suo WSDL siano raggiungibili via HTTP.
Poi lanci svcutil passandogli l'indirizzo del WSDL e ti genererà le classi proxy.

Comunque... ripercorriamo tutti i passi da capo.

1. Creo la libreria WCF e il progetto console.
2. Dal progetto console referenzio la libreria WCF e scrivo questo codice nel metodo Main del progetto console (tratto dalla documentazione) per ospitare il servizio. Nota come vengano esposti due endpoint: uno BasicHttpBinding per il servizio vero e proprio e uno MexHttpBinding per esporre il WSDL.
Nota anche che lo sto mettendo in ascolto sulla porta 8001 di localhost.
ServiceHost svcHost = new ServiceHost(typeof(Service1), new Uri("http://localhost:8001/"));
ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
    smb = new ServiceMetadataBehavior();
}

smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svcHost.Description.Behaviors.Add(smb);
svcHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
svcHost.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "");
svcHost.Open();

// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.
svcHost.Close();

In questo esempio, Service1 e IService1 sono rispettivamente l'implementazione concreta e l'interfaccia del mio servizio WCF. Nel tuo caso avranno altri nomi, presumo.

3. Adesso compilo e avvio il progetto console (se non riesce ad aprire la porta, avvialo come amministratore).
In output vedo questo, che mi dà conferma che il servizio è in ascolto.
The service is ready.
Press <ENTER> to terminate service.


Se voglio ulteriore conferma, vado nel browser e digito l'indirizzo che nel mio caso era:
http://localhost:8001

Riesco correttamente a vedere la pagina informativa del servizio che, tra l'altro, mi dice che il WSDL è ospitato a questo indirizzo:
http://localhost:8001/?wsdl


4. Quindi vado ad aprire il prompt dei comandi per sviluppatori di Visual Studio e digito:
svcutil http://localhost:8001/?wsdl /Language=c# /t:Code /out:ClassNameProxy.cs /config:ClassNameProxy.config


5. Nella directory corrente vengono generati i file ClassNameProxy.cs e ClassNameProxy.config.
Il file ClassNameProxy.cs lo sposto nell'applicazione ASP.NET Core, mentre il file .config lo posso pure eliminare. Il file config non mi serve perché posso configurare il client da codice C#.

6. Quindi nell'applicazione ASP.NET Core installo questo pacchetto Nuget. Da riga di comando, nella directory del progetto ASP.NET Core, scrivo:
dotnet add package System.ServiceModel.Http


7. Compilo l'applicazione ASP.NET Core e non dovrebbero esserci errori. Ora è il momento di istanziare il client e inviare la prima richiesta. Da qualche parte scrivo quanto segue, ad esempio nell'action di un controller di ASP.NET Core.
Nota come io stia usando la stessa configurazione del server (BasicHttpBinding e porta 8001 di localhost).
var binding = new BasicHttpBinding();
var address = new EndpointAddress("http://localhost:8001");
var client = new Service1Client(binding, address);
var data = await client.GetDataAsync(1);

In questo esempio il mio client si chiama Service1Client mentre nel tuo caso si potrebbe chiamare in altro modo. E' una classe definita dentro ClassNameProxy.cs. Cerca "Client" e la troverai.
Qui ho anche invocato l'operazione GetDataAsync(1). Nel tuo caso avrai altre operazioni. Usa l'intellisense per capire che chiamate puoi fare.

ciao,
Moreno
Modificato da BrightSoul il 03 settembre 2019 20:33 -

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.