far passare un array di byte tramite il webservice

Domanda far passare un array di byte tramite il webservice

  • venerdì 9 marzo 2012 11:48
     
     
    Ciao a tutti, 

    mi ritrovo ad avere un problema con la mia applicazione in silverlight 4.
    In pratica voglio far passare un array di byte che rappresenta un'immagine tramite il webservice. Finchè l'immagine non supera i 4 kb tutto va bene se li supera mi da l'errore "Quota per la lunghezza massima della matrice (16384) superata durante la lettura dei dati XML. Tale quota può essere incrementata modificando la proprietà MaxArrayLength dell'oggetto XmlDictionaryReaderQuotas utilizzato durante la creazione del lettore XML."

    guardando in giro ho trovato qualche soluzione che mi ha portato a modificare il web.config e il ServiceReferences.ClientConfig in questo modo:

    ServiceReferences.ClientConfig

    <configuration>
    <system.serviceModel>
    <bindings>
    <basicHttpBinding>
    <binding name="BasicHttpBinding_ICespitiAVService" closeTimeout="02:00:00" openTimeout="02:00:00" receiveTimeout="02:00:00" sendTimeout="02:00:00"
    maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
    <security mode="None" />
    </binding>
    </basicHttpBinding>
    </bindings>
    <client>
    <endpoint address="http://localhost:51366/CespitiAVService.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICespitiAVService"
    contract="CespitiAVService.ICespitiAVService" name="BasicHttpBinding_ICespitiAVService" />
    </client>
    </system.serviceModel>
    </configuration>

    web.config

    <bindings>
    <basicHttpBinding>
    <binding name="BasicHttpBinding" maxBufferSize="2147483647" closeTimeout="02:00:00"
    openTimeout="02:00:00" receiveTimeout="02:00:00" sendTimeout="02:00:00"
    maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
    <readerQuotas maxDepth="64" maxStringContentLength="2147483647"
    maxArrayLength="67108864" maxBytesPerRead="2147483647"
    maxNameTableCharCount="2147483647" />
    </binding>
    </basicHttpBinding>
    </bindings>
    <client>
    <endpoint></endpoint>
    </client>

    queste modifiche però non mi hanno portato a nulla

    da quanto ho letto dovrei modificare i readerQuotas anche lato client ma non mi è possibile farlo dato che mi dice che bindings vuol solo nodi figli di tipo security.

    come posso fare per raggiungere il mio scopo?

Tutte le risposte

  • venerdì 9 marzo 2012 11:58
     
      Contiene codice

    ciao

    devi aggiungere questo

              <readerQuotas maxArrayLength="1000000"/>
    

    dentro il tag binding sul client


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

  • venerdì 9 marzo 2012 12:01
     
     

    Ciao zizzi,

    You wrote on 09/03/2012 :

    come posso fare per raggiungere il mio scopo?

    paginando l'invio del blob a chunk, non hai alternative anche se cambi i settaggi di wcf prima o poi ti scontrerai di nuovo con il limite imposto.

    .m



    blog @ //milestone.topics.it
  • venerdì 9 marzo 2012 12:04
     
      Contiene codice

    ciao

    devi aggiungere questo

              <readerQuotas maxArrayLength="1000000"/>

    dentro il tag binding sul client


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

    non posso farlo perchè il nodo binding nel client config non mi accetta i readerquotas
  • venerdì 9 marzo 2012 12:07
     
     

    Ciao zizzi,

    You wrote on 09/03/2012 :

    come posso fare per raggiungere il mio scopo?

    paginando l'invio del blob a chunk, non hai alternative anche se cambi i settaggi di wcf prima o poi ti scontrerai di nuovo con il limite imposto.

    .m



    blog @ //milestone.topics.it
     sì avevo pensato di fare una paginazione ma, dato che so per certezza che la dimensione degli array che passo attraverso il webservice non supererà mai una determinata soglia(questo perchè le immagini che devo far passare non supereranno mai il MByte), avrei preferito evitare una cosa del genere e speravo ci fosse una soluzione fattibile tramite le modifiche delle impostazioni del wcf
  • venerdì 9 marzo 2012 12:09
     
      Contiene codice

    ciao

    devi aggiungere questo

              <readerQuotas maxArrayLength="1000000"/>

    dentro il tag binding sul client


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy

    non posso farlo perchè il nodo binding nel client config non mi accetta i readerquotas

    non conosco bene silverlight quindi potrebbe anche essere che non supporti questa cosa, ma su ogni altro tipo di client wcf funziona così

    devi innalzare il MaxReceivedMessageSize sul binding, e nei suoi readerQuotas il maxArrayLength perchè passi 1 array di bytes...

    a presto


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

  • venerdì 9 marzo 2012 13:10
     
      Contiene codice

    ciao

    devi aggiungere questo

              <readerQuotas maxArrayLength="1000000"/>

    dentro il tag binding sul client


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy

    non posso farlo perchè il nodo binding nel client config non mi accetta i readerquotas

    non conosco bene silverlight quindi potrebbe anche essere che non supporti questa cosa, ma su ogni altro tipo di client wcf funziona così

    devi innalzare il MaxReceivedMessageSize sul binding, e nei suoi readerQuotas il maxArrayLength perchè passi 1 array di bytes...

    a presto


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

    da esempi che ho trovato su vari siti avevo visto che veniva sempre detto che bisogna modificare le impostazioni dei readerquotas lato client come tu hai detto, questo anche su silverlight

    il fatto è che non ho idea del perchè ma io non riesco proprio a modificare questi parametri dato che sembra non esista proprio la proprietà readerquotas nei binding

    potrebbe essere che abbia dimenticato qualche cosa, ma più che aggiungere la dll windows.servicemodel non dovrebbe essere necessario fare nulla o mi sbaglio?


  • venerdì 9 marzo 2012 13:29
     
     

    ciao

    verifica 1 cosa: è l'intellisense del .config che non ti fa vedere il tag, o davvero ti solleva 1 eccezione?

    nel caso è solo l'intellisense, allora aggiungi lo stesso la configurazione dentro il binding


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

  • venerdì 9 marzo 2012 13:40
     
     

    ciao

    verifica 1 cosa: è l'intellisense del .config che non ti fa vedere il tag, o davvero ti solleva 1 eccezione?

    nel caso è solo l'intellisense, allora aggiungi lo stesso la configurazione dentro il binding


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

    è una delle cose che ho provato per prima e da proprio eccezione
  • venerdì 9 marzo 2012 13:41
     
     

    puoi postare l'eccezione completa con l'innerexception (se esite)??

    grazie


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

  • venerdì 9 marzo 2012 13:46
     
     

    Se ho capito bene intendi l'eccezione che da se inserisco i readerquotas

    InvaliOperationException

    Elemento 'readerQuotas' non riconosciuto nella configurazione di riferimento al servizio. Solo un subset della funzionalità di configurazione di Windows Communication Foundation è disponibile in Silverlight.

       su System.ServiceModel.Configuration.BasicHttpBindingElement.ReadXml(XmlReader reader)
       su System.ServiceModel.Configuration.BasicHttpBindingCollectionElement.ReadXml(XmlReader reader)
       su System.ServiceModel.Configuration.BindingsSection.ReadXml(XmlReader reader)
       su System.ServiceModel.Configuration.ServiceModelSectionGroup.ReadXml(XmlReader reader)
       su System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup()
       su System.ServiceModel.Configuration.ServiceModelSectionGroup.get_Current()
       su System.ServiceModel.Description.ConfigLoader.LookupChannel(String configurationName, String contractName, Boolean wildcard)
       su System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)
       su System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)
       su System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
       su System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)
       su System.ServiceModel.EndpointTrait`1.CreateSimplexFactory()
       su System.ServiceModel.EndpointTrait`1.CreateChannelFactory()
       su System.ServiceModel.ClientBase`1.CreateChannelFactoryRef(EndpointTrait`1 endpointTrait)
       su System.ServiceModel.ClientBase`1.InitializeChannelFactoryRef()
       su System.ServiceModel.ClientBase`1..ctor()
       su CespitiAV.CespitiAVService.CespitiAVServiceClient..ctor()
       su CespitiAV.Login.OKButton_Click(Object sender, RoutedEventArgs e)
       su System.Windows.Controls.Primitives.ButtonBase.OnClick()
       su System.Windows.Controls.Button.OnClick()
       su System.Windows.Controls.Primitives.ButtonBase.OnKeyUpInternal(Key key)
       su System.Windows.Controls.Primitives.ButtonBase.OnKeyUp(KeyEventArgs e)
       su System.Windows.Controls.Control.OnKeyUp(Control ctrl, EventArgs e)
       su MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)

    non c'è innerexception

    • Modificato zizzi venerdì 9 marzo 2012 13:47
    •  
  • venerdì 9 marzo 2012 14:27
     
     

    intanto mi è stato consigliato di trasformare l'array di byte in una string in base64

    ma non si risolve il "problema" dato che supero il MaxStringContentLength  e sempre per il motivo precedente non posso modificarne l'impostazione

  • venerdì 9 marzo 2012 16:29
     
     

    ciao

    prova a prendere un esempio di WCF per silverlight (è tra i template di silverlight), da li prenditi il config con dentro il customBinding

    nel custom binding dovresti poter impostare la dimensione che vuoi anche da silverlight


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

  • lunedì 12 marzo 2012 14:31
     
     

    ciao

    prova a prendere un esempio di WCF per silverlight (è tra i template di silverlight), da li prenditi il config con dentro il customBinding

    nel custom binding dovresti poter impostare la dimensione che vuoi anche da silverlight


    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

    ho provato con il customBindings e anche in questo caso non mi permette di inserire i readerquotas

    ho provato a mandare l'array a blocchi salvandomeli momentaneamente lato server per poi ricomporli, però a quanto pare non riesco a farlo perchè ogni pacchetto che mando tramite il webservice viene sì salvato lato server ma poi al successivo passaggio al webservice quel pacchetto non è più disponibile quindi ogni volta che provo a ricomporre l'array dei byte lavoro con il nulla perchè tutto è andato perso, praticamente è come se ad ogni passaggio al webservice si resetti tutto

    ho cercato di fregare il webservice scompattando l'array di byte e mettendoli all'interno di una lista (ho provato con una immagine che si traduce in un array da 22000 byte, l'ho diviso in array da 15000 byte e questi li ho salvati in una lista di array di byte, il risultato è una lista di 19 array da 15000 byte l'uno e che quindi dovrebbe rispettare il limite di 16000 e rotti elementi degli array imposto dal wcf) il problema è che in questo caso mi viene dato errore 400 bad request

    l'ultima operazione per immagini di 4kb, l'ho provato facendo divisioni di 200 byte così da creare più array e funziona

    sto iniziando a finire le idee al riguardo...


    • Modificato zizzi lunedì 12 marzo 2012 14:32
    •  
  • lunedì 12 marzo 2012 15:07
     
     
    devi supportare le reliablesession per fare 1 cosa del genere sul servizio altrimenti è normale che ad ogni chiamata il servizio non sappia ciò che hai fatto in quella precedente, ma non so se SL li supporta

    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

  • lunedì 12 marzo 2012 15:13
     
     
    devi supportare le reliablesession per fare 1 cosa del genere sul servizio altrimenti è normale che ad ogni chiamata il servizio non sappia ciò che hai fatto in quella precedente, ma non so se SL li supporta

    Antonio Esposito [MCT, MCPD, MCTS, MCP]
    dotnetlombardia.org | blog | web | @tonyexpo
    Italy
     

    immagino tu stia parlando dell'invio dei pacchetti uno ad uno via webservice per poi ricomporli lato server, comunque purtroppo SL4 non supporta le reliablesession
  • mercoledì 14 marzo 2012 16:03
     
     

    alla fine ho raggiunto lo scopo finale ma non sono riuscito a risolvere il problema di come passare al webservice array con più di 16000 e rotti oggetti al suo interno.

    Comunque scrivo la mia soluzione per due motivi: 1) potrebbe essere utile ad altri 2) la mia soluzione è sinceramente pietosa quindi se qualcuno ha idee migliori sono ben accette.

    La mia soluzione rispecchia la soluzione proposta da Mauro Servienti, in pratica passo array da 16k oggetti al webservice con un intero che indica il numero del pacchetto, dopodichè, dato che l'array di byte lo devo salvare su database, sfrutto quest'ultimo come una sorta di buffer recuperando l'array salvato e inserendoci i byte nella posizione esatta e poi salvando l'array modificato su database. Alla fine su database sarà salvato l'array che rappresenta esattamente l'immagine.

    come ho detto la mia soluzione non è per niente bella però almeno funziona, se avete proposte migliori sono ben accette.