Ricevere dati Json

giovedì 18 settembre 2014 - 11.50
Tag Elenco Tags  C#  |  .NET 4.0

marco.morgia Profilo | Junior Member

Buongiorno a tutti,

sto lavorando su un progetto dove, un microcontrollore con Linux dovrebbe andare a popolare un DB tramite una chiamata a WCF.
Visto che non si riesce a far comunicare il dispositivo Linux con il servizio WCF (se non andando a cambiare profondamente il servizio già attivo), si era pensato di far una post in Json su una pagina web, poi da tale pagina web (asp.net) richiamare il servizio WCF e inserire nel DB i dati che ricevo dalla Json.

Qualcuno ha già fatto qualcosa di simile? Se si come avete fatto?

Grazie

0v3rCl0ck Profilo | Guru

Ciao,

Io ti consiglio di rivedere la possibilità di fare alcune modifiche a WCF, perchè molte modifiche possono essere fatte semplicemente da configurazione, senza cambiare un riga di codice dell'attuale implementazione. Immagino che il tuo problema di comunicazione tra microcontrollore e wcf, sia che wcf è configurato tipo in wshttpbinding o peggio tcp, quindi pure con la security attiva di default, e posso capire che non ci si salti fuori cercando di fare una chiamata da un dispositivo che non conosce l'implementazione .net

Detto questo penso tu possa provare ad aggiungere un binding tipo basichttpbinding, che lavora sempre in soap, ma almeno ha una struttura semplificata, oppure il massimo sarebbe un webhttpbinding che ti permetterebbe di avere un servizio REST, e quindi semplicemente richiamabile con un qualisasi rest client / web client, che ci sono per tutti i linguaggi di programmazione o architetture.

Ad esempio in questo post, il tizio ha configurato lo stesso servizio wcf per essere esposto contemporaneamente in wsHttpBinding + basicHttpBinding + webHttpBinding: http://knowledgebaseworld.blogspot.it/2010/06/wcf-service-with-webhttpbinding.html

con il webHttpBinding puoi anche cambiare il default Uri template per renderlo "più" rest, sfruttando l'attributo WebGet/WebInvoke/ecc... per comandare l'uri template e i verb http: http://www.codeproject.com/Articles/571813/A-Beginners-Tutorial-on-Creating-WCF-REST-Services

Altrimenti anche la tua soluzione è più che accettabile, diventerebbe un proxy di mezzo, che ti permette di comunicare con altri tipi di device, per poi comunicare con la parte interna WCF che tra l'altro in quel modo, potrebbe anche rimanere nella rete interna privata e non essere neanche esposta al pubblico.

Quindi riassumendo, direi che se il tuo servizio WCF è già esposto pubblicamente, e puoi aggiungere un semplice binding, direi che è la soluzione migliore perchè ti evita di aggiungere altra infrastruttura; invece se ti ritrovi a dovere modificare anche l'applicazione per aggiungere attributi o modificare profondamente l'implementazione, allora la tua idea di mettere un qualsiasi rest/web service semplice di mezzo penso sia la migliore alternativa.


Michael Denny | Visual C# MVP
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
http://mvp.microsoft.com/mvp/Michael%20Denny-5000735
Twitter: @dennymic

marco.morgia Profilo | Junior Member

Grazie per la risposta.

Purtruppo i dati che ricevo non sono proprio Json ( il programma che gira sul controllore purtroppo non l'ho fatto io, e non si può modificare al momento ),
ma ricevo tutto in multipart. Sono un po' in difficoltà a creare il metodo per ricevere i dati.

Quello che mi invia il dispositivo è

<form action="http://xxx.xxx.xxx.xxx:56" method="post" enctype="multipart/form-data" style="width 900px;" >
<p><input type="text" name="text" value='{"request":"get_setup","value":{ "server": { "ip": "79.55.107.30", "port": 80 }, "loggers": [ { "producer": "aaaa", "logid": [ 76, 79, 71, 0, 16, 153 ], "logname": "nomeprimo", "ptype": "LOG_TEMP", "max": 25.000000, "min": 22.000000, "period": 30 }, { "producer": "aaaaa", "logid": [ 76, 79, 71, 0, 17, 75 ], "logname": "nomesec", "ptype": "LOG_TEMP_HUM", "max": 30.000000, "min": 22.000000, "period": 30 } ] }} } '>
<p><button type="submit">Submit</button>
</form>

0v3rCl0ck Profilo | Guru

se ti invia tutta quella "sbrodolata" senza una minima codifica decente, allora direi che la tua soluzione di fare un pagina di mezzo proxy, sia effettivamente la soluzione migliore, perchè a quel punto fai un tuo handler generico, senza sfruttare nessun framework specifico (no wcf, no web service, no web api), solo un buon vecchio generic handler (oppure un action mvc che prenda una stringa come parametro), perchè hai bisogno di avere controllo sul flusso di dati che ti arriva, una volta letto il malloppazzo, estrapoli quel json che è contenuto nel tag input, e poi quello essendo un json puoi sfruttare direttamente il javascriptserializer per riempire un oggetto .net per poi richiamare il tuo servizio wcf.


Michael Denny | Visual C# MVP
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
http://mvp.microsoft.com/mvp/Michael%20Denny-5000735
Twitter: @dennymic

marco.morgia Profilo | Junior Member

E' quello che ho fatto, quindi per intenderci ho creato una Action che riceve una stringa come parametro,

public string Index(string parametro)
{
return "Ricevuto";

}

però il parametro è a null.

0v3rCl0ck Profilo | Guru

nel tuo caso non va bene, perchè ti arriva roba non formattata, e l'handler di mvc si aspetta di vedere del json/xml nei dati di post per potere fare il mapping dati post <-> parametri controller action... quindi ti consiglio di crearti un tuo custom RouteHandler, che ti permette di avere pieno controllo sulla richiesta, ma di sfruttare il routing di mvc, quindi di poterlo integrare in un progetto mvc in modo non invasivo e senza dovere usare i "vecchi" GenericHandler .ashx (che puoi comunque utilizzare, vedi te, poco cambia per quello che devi fare).

Per comodità ho trovato questo: http://stackoverflow.com/a/17893416

che riporto qua sotto:

public class RouteHandler : IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { HttpHanler httpHandler = new HttpHanler(); return httpHandler; } public class HttpHanler : IHttpHandler { public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { var routeValues = context.Request.RequestContext.RouteData.Values; string file = context.Request.RequestContext.RouteData.Values["img"].ToString(); // anything you can do here. context.Response.ContentType = "image/jpeg"; context.Response.BinaryWrite("~/cat.jpg"); context.Response.End(); } } }

che nel global.asax vai a registrare così:

routes.Add(new Route("Thumb/{img}", new RouteHandler()));

dai un nome appropriato alla classe e via... in questo modo potrai fare il tuo parser super customizzato per capire che metodi devi richiamare e che parametri passare.


Michael Denny | Visual C# MVP
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
http://mvp.microsoft.com/mvp/Michael%20Denny-5000735
Twitter: @dennymic
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5