Creare un servizio WCF che invia e riceve array byte - Parte 2

Seconda e ultima parte per la creazione di un servizio per la gestione dei file.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

Riprendiamo l'articolo precedente https://www.iprogrammatori.it/articoli/microsoft-net-framework/art_net-wcf-creare-un-servizio-che-invia-e-r_1636.aspx per la gestione dei file tramite i servizi di Windows Communication Foundation, in particolare in questa seconda ed ultima parte come inviare il file dalla pagina web al servizio, ossia da un progetto di tipo Asp.Net ad un servizio WCF.

Senza ricreare un nuovo progetto, apriamo il precedente progetto, e dopo aver selezionato il progetto del servizio, andiamo nel file del servizio.

Ora dobbiamo scrivere il codice per inviare il file, dalla pagina web al servizio. In questo modo vediamo come rendere la nostra applicazione bidirezionale.
Ritorniamo sul progetto del servizio e nel file Service1 dobbiamo scrivere il metodo per la ricezione del flusso dati di un file.
Il metodo avrà due parametri, uno di tipo stringa per assegnare il nome del file e l’altro l’array di byte per creare il file
Qui di seguito si riporta la dichiarazione per entrambi i linguaggi.

VB.Net
Public Function CreaFile(NomeFile As String, StreamFile As Byte()) As Boolean Implements IService1.CreaFile
Try
File.WriteAllBytes("D:\" + NomeFile, StreamFile)
Catch ex As Exception
Return False
End Try
End Function
C#
public bool CreaFile(string NomeFile, byte[] StreamFile)
{
try
{
File.WriteAllBytes("D:\\" + NomeFile, StreamFile);
return true;
}
catch (Exception ex)
{
return false;
}
}

Andiamo nel file di interfaccia, ed impostiamo il nuovo metodo.
Qui di seguito si riporta tale dichiarazione.

VB.Net
<OperationContract()>
Function CreaFile(NomeFile As String, StreamFile As Byte()) As Boolean
C#
[OperationContract]
bool CreaFile(string NomeFile, byte[] StreamFile);

Ora ritorniamo nel progetto web, e scriviamo il codice per inviare il file al servizio con il metodo creato.
La prima operazione da fare è quella di aggiornare il servizio web, in modo che viene visto il nuovo metodo creato.
Nella nostra pagina web, facciamo click sul pulsante con la dicitura “Invia” con il quale andremo ad eseguire il metodo appena creato.
Qui di seguito si riporta il codice per l’evento click di tale pulsante.

VB.Net
Protected Sub BtnInvia_Click(sender As Object, e As EventArgs) Handles BtnInvia.Click
Try
Dim StreamFile As Byte() = File.ReadAllBytes("D:\\MioFile.jpg")
Dim ServizioDati As New WsDati.Service1Client
ServizioDati.CreaFile("NuovissimoFile.Jpg", StreamFile)
Catch ex As Exception
Response.Write("Errore: " + ex.Message)
'Errore: Il server ha restituito una risposta non prevista: (400) Bad Request.
End Try
End Sub
C#
protected void BtnInvia_Click(object sender, EventArgs e)
{
try
{
byte[] StreamFile = File.ReadAllBytes("D:\\MioFile.jpg");
WSDati.Service1Client ServizioDati = new WSDati.Service1Client();
ServizioDati.CreaFile("NuovissimoFile.Jpg", StreamFile);
}
catch (Exception ex)
{
//Il server ha restituito una risposta non prevista: (400) Bad Request.
Response.Write("Errore: " + ex.Message);
}
}

Non appena facciamo la prova verrà generato il seguente errore “Errore: Il server ha restituito una risposta non prevista: (400) Bad Request.” questo perché dobbiamo modificare il file di configurazione per l’invio dei file.

Questo è dovuto alla mancanza dei parametri impostati nel file di configurazione del servizio, in particolare nel file “WebConfig”.

Il file di configurazione avrà questi parametri:

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Per evitare la diffusione di informazioni sui metadati, impostare i valori seguenti su false prima della distribuzione -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Per ricevere i dettagli sull'eccezione per scopi di debug in caso di guasti, impostare il valore riportato sotto su true. Impostarlo su false prima della distribuzione per evitare di diffondere informazioni sull'eccezione -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Per sfogliare la directory radice dell'applicazione Web durante il debug, impostare il valore riportato sotto su true.
Impostarlo su false prima della distribuzione per evitare di diffondere informazioni sulla cartella dell'applicazione Web.
-->
<directoryBrowse enabled="true"/>
</system.webServer>

Per risolvere questo problema andranno aggiunti i seguenti parametri tra </behaviors> e <protocolMapping> in modo che si possono trasmettere flussi di dati maggiore.

<bindings>
<basicHttpBinding>
<binding name="wccServiceBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed" sendTimeout="00:50:00" receiveTimeout="00:50:00">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

</binding>
<binding name="ADHOC_WSSoap11Binding"  messageEncoding="Mtom"/>
</basicHttpBinding>
<customBinding>
<binding name="ADHOC_WSSoap12Binding">
<mtomMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<services>
<service name="WcfServizioVB.Service1">
<endpoint behaviorConfiguration="" binding="basicHttpBinding" bindingConfiguration="wccServiceBinding" contract="WcfServizioVB.IService1" />
</service>
</services>

E nella parte tra <directoryBrowse enabled="true"/> e </system.webServer> inserire il seguente codice

<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647">
<headerLimits>
<add header="Stream" sizeLimit="2147483647" />
</headerLimits>
</requestLimits>
</requestFiltering>
</security>

Ora se testiamo il nostro codice  vedremo che l’applicazione funziona correttamente senza generare errore.
Nella parte server, verrà creato il file sul computer.


Conclusioni


L’articolo ha fornito al lettore una tecnica per l’utilizzo dei servizi WCF per l’invio e la ricezione dei file.
Implementazione che solo tramite l’inserimento di alcuni parametri nel file di configurazione, permette tale gestione. La gestione dei file con i servizi web non è semplice, ma con le giuste ed opportune modifiche si riescono a superare le difficoltà di questo scenario.