527 messaggi dal 18 dicembre 2012
Ciao a tutti

Ho creato un servizio WCF:

[IService.cs]
namespace Service
{
    [ServiceContract]
    interface IService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Configuration")]
        ConfigurationResponse Configuration(ConfigurationRequest xml);
    }
}


Ho questo problema: nel caso di nessun errore devo restituire un xml che ha un struttura definita dalla classe ConfigurationResponse, mentre nel caso di errore devo restituire un xml che ha questa struttura:

<Errors>
  <Error>Errore1</Error>
  <Error>Errore2</Error>
  <Error>Errore3</Error>
</Errors>


Come faccio a realizzare questo?

Ho pensato di restituire una stringa com risultato di 'Configuration', ma non credo sia possibile dato che ResponseFormat ha solo 2 voli 'xml' e 'json'

Grazie mille
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao, proviamo a vedere se riusciamo a restituire entrambi i tipi di XML senza cambiare il tipo restituito da Configuration.

Per segnalare l'errore potresti sollevare un'eccezione, magari è una strada percorribile.
Per il momento decora Configuration con questo ulteriore attributo FaultContract:
[OperationContract]
[FaultContract(typeof(Errors))]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Configuration")]
        ConfigurationResponse Configuration(ConfigurationRequest xml);


Dove "Errors" sarà una classe tipo questa che dovrai creare.
public class Errors : List<string>
{
}


Quando si verifica una situazione d'errore nella tua operazione Configuration, solleva l'eccezione in questo modo:
if (tuaCondizioneDErrore) {
  var errors = new Errors();
  errors.Add("Errore1");
  errors.Add("Errore2");
  errors.Add("Errore3");
  throw new FaultException<Errors>(errors);
}


Vedi che output ti restituisce. Se funziona, potrai continuare ad usare ConfigurationResponse come tipo restituito.


Come faccio a realizzare questo?

Dato che - mi sembra di capire - devi conformarti ad un protocollo di comunicazione che ti viene fornito dal client, forse sarebbe più semplice usare ASP.NET WebAPI anziché WCF.

ciao,
Moreno

Enjoy learning and just keep making
527 messaggi dal 18 dicembre 2012
Ciao Moreno
ricevevo errore:
System.ServiceModel.FaultException`1 was unhandled by user code

Ma era un problema di vs e mi è bastato deselezioanre delle check in strumenti -> opzioni

Una domanda: Chi richiede il servizio non è detto che utilizzi .net, cosa riceve quando si verifica una FaultException? Il sistema con cui devo interfacciarmi, di cui conosco nulla, si aspetta un xml in questo formato
<Errors>
<Error>Errore 1</Error>
<Error>Errore 2</Error>
<Error>Errore 3</Error>
</Errors>

Grazie
Modificato da Svipla il 07 giugno 2017 16.43 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
ho visto anche gli altri tuoi post. Penso che dovresti cambiare tecnologia e provare a farlo con ASP.NET Web API che riuscirai a piegare moooooooolto più facilmente alle esigenze di chi ti ha passato il protocollo di comunicazione.

WCF è eccezionale perché supporta molte funzionalità ma è indicato se le parti (client e server) comprendono il protocollo SOAP.

In questo caso, il tuo client vuole semplicemente inviare XML su HTTP e penso che con WCF incontreresti numerosi ostacoli. Non che sia impossibile da fare, intendiamoci, ma... perché forzarsi a proseguire sulla strada più ardua?

ciao,
Moreno

Enjoy learning and just keep making
527 messaggi dal 18 dicembre 2012
Ciao Moreno e ancora grazie
Anche per le web api, non mi è mai capitato di crearle.
Sai consigliarmi un tutorial ottimo?
Penso che con le web si può richiamare un servizio con il protocollo http, giusto?

Mi sai spiegare perchè nel serializzare una List<string> mi aggiunge '<a:string>' e perchè se inserisco nel request i campi in un certo ordine ricevo null quando vado a leggere?

Grazie
Modificato da Svipla il 08 giugno 2017 10.50 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,

Penso che con le web si può richiamare un servizio con il protocollo http, giusto?

assolutamente sì, sono pensate per questo.


Mi sai spiegare perchè nel serializzare una List<string> mi aggiunge '<a:string>'

Qui chi produce l'XML è il DataContractSerializer, che si comporta in osservazione di alcune regole del protocollo SOAP. Siccome il tuo client non ha intenzione di usare il protocollo SOAP, ecco che ti trovi a combattere per eliminare queste particolarità.


e perchè se inserisco nel request i campi in un certo ordine ricevo null quando vado a leggere?

Perché per il DataContractSerializer l'ordine è importante. Semplicemente, non puoi scombussolare i nomi delle proprietà come capita, altrimenti potresti trovarti con alcuni valori null proprio come hai osservato.

Ne consegue che usare il DataContractSerializer non fa al caso tuo. E' ottimo in altre situazioni, per esempio quando sia client che server usano il protocollo SOAP, ma non in questo caso.

Ti linko invece un progetto ASP.NET WebAPI che ti mostra come buttar fuori due tipi di risultato, proprio come serviva a te.
https://1drv.ms/u/s!Ao4rhSdtDw8rgedvQ5otD6wvxuoXUg

Cose che troverai in questo progetto.
  • La classe che trovi in Controllers/GetData.cs, che è quella che riceverà le richieste a /GetData. Lì dentro trovi un metodo che risponderà alle richieste POST. Questo metodo accetta un numero: se è minore di 10, restituirà un risultato, altrimenti gli errori.
  • Dopo aver lanciato l'applicazione in debug, visita /swagger, vedrai una fantastica pagina interattiva che ti mostrerà tutte le operazioni nel tuo servizio e ti permetterà di invocarle senza che tu debba creare un'applicazione di test.
  • Le classi che trovi dentro Model sono quelle che vengono restituire al client. Le ho decorate con degli attributi tipo XmlRoot per determinare come dovranno presentarsi in XML. Sarà importante per te imparare ad usare questi attributi. Li trovi elencati qui: https://docs.microsoft.com/en-us/dotnet/framework/serialization/controlling-xml-serialization-using-attributes
  • Nella cartella Formatters trovi una classe che ti consente di controllare la serializzazione XML. Per esempio, se vuoi che nell'output NON venga inclusa la dichiarazione XML, è lì che devi intervenire. Ti ho commentato la riga di codice da usare.



Sai consigliarmi un tutorial ottimo?

Qui su Aspitalia abbiamo tanti contenuti che riguardano ASP.NET WebAPI, parti da questo articolo di Andrea Colaci.
http://www.aspitalia.com/articoli/asp.net-mvc/scrivere-servizi-rest-asp.net-web-api.aspx

ciao,
Moreno
Modificato da BrightSoul il 10 giugno 2017 12.09 -

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.