Autore Topic: Accesso a WCF .NET 4.5 service asincrono usante async/await  (Letto 899 volte)

Offline mistral61

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire z
  • Sistema operativo:
    Windows 7
Accesso a WCF .NET 4.5 service asincrono usante async/await
« il: 05 Aprile 2013, 23:48:52 CEST »
0
Ho un WCF service .NET 4.5 con questa interfaccia
Codice (C#): [Seleziona]
[OperationContract]
[WebInvoke(Method = "POST",
    BodyStyle = WebMessageBodyStyle.Wrapped,
    UriTemplate = "UpdCategorieArticoli",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json)]
Task<JsonGenericResponse> UpdCategorieArticoli(string jsonData);

L' implementazione è così:
Codice (C#): [Seleziona]
public async Task<JsonGenericResponse> UpdCategorieArticoli(string jsonData)
{
    JsonGenericResponse objWmJson = new JsonGenericResponse();
    objWmJson.IsInError = "true";
    try
    {
        DataIfCloudEspresso objData = new DataIfCloudEspresso();
        string xmlData = <some transformation from json>;
        int intUpdatedCount = await objData.UpdCategorieArticoli(xmlData );
        if (intUpdatedCount == 1)
        {
            objWmJson.IsInError = "false";
            objWmJson.Value = intUpdatedCount.ToString();
        }
        return objWmJson;
    }
}
La JsonGenericResponse  è una comune classe .NET con Get/Set

Nel data layer il metodo è questo:
Codice (C#): [Seleziona]
public async Task<int> UpdCategorieArticoli(string xmlData)
{
    try
    {
        using (SqlConnection objConn = new SqlConnection(base.ConnectionString))
        {
            using (SqlCommand cmdADO = new SqlCommand("spUpd_CategorieArticoli", objConn))
            {
                cmdADO.Parameters.Add(new System.Data.SqlClient.SqlParameter("@XMLDoc", SqlDbType.Text));
                cmdADO.Parameters["@XMLDoc"].Value = xmlData;
                cmdADO.Parameters.Add(new System.Data.SqlClient.SqlParameter("@RETURN_VALUE", SqlDbType.Int));
                cmdADO.Parameters["@RETURN_VALUE"].Direction = ParameterDirection.ReturnValue;
                //
                cmdADO.CommandType = CommandType.StoredProcedure;
                //
                await objConn.OpenAsync();
                await cmdADO.ExecuteNonQueryAsync();
                return (int)cmdADO.Parameters["@RETURN_VALUE"].Value;
            }
        }
    }
}

Da Jquery funziona , con un codice tipo
Codice (js): [Seleziona]
$.ajax({
    type: "POST",
    url: "WEspresso.svc/UpdCategorieArticoli",
    data: strData,
    async: true,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    complete: saveCategorieArticoli_onComplete
});
nel callback vedo il mio json di ritorno.

Invece da Android ho dei problemi, il codice è

Codice (Java): [Seleziona]
public class wsWcfUpdCateg extends AsyncTask<String, Integer, String>{
    public final String SOAP_ACTION = "[url=http://tempuri.org/UpdCategorieArticoli";]tempuri - Bing[/url]
    public  final String SOAP_ADDRESS = "http://192.168.0.1/CloudTest/wespresso.svc/UpdCategorieArticoli";
public Context maincontext;
HttpResponse objResponse = null;

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);            
}

@Override
protected String doInBackground(String... arg0) {
    StringBuilder objString = new StringBuilder();
    try
    {
        HttpClient objHttpClient = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(objHttpClient.getParams(), 10000);
        JSONObject json = new JSONObject();
        HttpPost objPost = new HttpPost(SOAP_ADDRESS);
        //
        ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("jsonData", arg0[0].toString()));
        for (NameValuePair p : params){
            json.put(p.getName(), p.getValue());
        }        
        StringEntity se = new StringEntity(json.toString());
        objPost.setEntity(se);
        objPost.setHeader("Accept", "application/json");
        objPost.setHeader("Content-type", "application/json");  
        objResponse = objHttpClient.execute(objPost);              
        StatusLine objStatusLine = objResponse.getStatusLine();
        Integer intStatus = objStatusLine.getStatusCode();              
        //
        return objString.toString() ;    
    }  
}

Che eseguito con codice tipo
Codice (Java): [Seleziona]
wsWcfUpdCateg objWs = (wsWcfUpdCateg) new wsWcfUpdCateg();
objWs.maincontext = MainActivity.this;
objWs.execute("{'CategoriaArticoliID':'26','CheckStamp':'711709','CategoriaArticoloPadreID':'5','Nome':'Whisky','Descrizione':'test'}");  
mi torna status 400

Se chiamo un codice WCF sincrono (con codice Android identico) che non torni Task<JsonGenericResponse> ma <JsonGenericResponse> invece tutto ok.

Visto che da browser funziona è evidente che manca qualcosa, ma dopo una settimana che cerco su Google ho ricavato niente.
Se qualcuno sa darmi indicazioni, grazie.

Post unito: 06 Aprile 2013, 00:00:17 CEST
postilla: nel codice scrivo tempuri.org/updcategoriearticoli , ma non so perchè l' editor ci mette "Bing"...boh
« Ultima modifica: 06 Aprile 2013, 10:23:30 CEST da Ricky` »

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Accesso a WCF .NET 4.5 service asincrono usante async/await
« Risposta #1 il: 06 Aprile 2013, 10:27:32 CEST »
0
Facendo riferimento a questa linea:

Codice (Java): [Seleziona]
objWs.execute("{'CategoriaArticoliID':'26','CheckStamp':'711709','CategoriaArticoloPadreID':'5','Nome':'Whisky','Descrizione':'test'}");  
ti faccio notare che JSON vuole i doppi apici e non gli apici singoli, magari il deserializer del tuo servizio rompe per questo.

Detto questo io proverei a debuggare la chiamata http che viene fatta da JQuery e valutarne il formato e gli header che vengono inseriti.

Offline mistral61

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire z
  • Sistema operativo:
    Windows 7
Re:Accesso a WCF .NET 4.5 service asincrono usante async/await
« Risposta #2 il: 06 Aprile 2013, 13:37:46 CEST »
0
Se chiamo una versione sync del metodo quel JSON è accettato.
Ad esempio questo funziona, ma è meno scalabile:
    public JsonGenericResponse UpdCategorieArticoliSync(string jsonData)
    {
        Task<JsonGenericResponse> objTest = UpdCategorieArticoli(jsonData);
        JsonGenericResponse objRet = new JsonGenericResponse();
        objRet.Value = objTest.Result.Value;
        ... ecc
        return objRet;
    }

Posso giusto provare gli apici doppi  per dire di averle provate tutte.

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Accesso a WCF .NET 4.5 service asincrono usante async/await
« Risposta #3 il: 06 Aprile 2013, 14:44:28 CEST »
0
Ok e per quanto riguarda il debug della chiamata http fatta da javascript?

Offline mistral61

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire z
  • Sistema operativo:
    Windows 7
Re:Accesso a WCF .NET 4.5 service asincrono usante async/await
« Risposta #4 il: 06 Aprile 2013, 23:24:43 CEST »
0
Ho guardato con Fiddler che fa ma non trovo qualcosa che mi possa aiutare, mi sembra la solita chiamata standard; del resto sono abbastanza esperto ma di alcune cose non è che sia proprio un guru.
Provo la strada WebView , se funziona così mi va bene.

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3487
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Accesso a WCF .NET 4.5 service asincrono usante async/await
« Risposta #5 il: 07 Aprile 2013, 11:41:33 CEST »
0
Vedi tu.
Io cercherei di valutare le differenze che ci sono tra la chiamata fatta da js e quella fatta da Android.

Offline mistral61

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire z
  • Sistema operativo:
    Windows 7
Re:Accesso a WCF .NET 4.5 service asincrono usante async/await
« Risposta #6 il: 07 Aprile 2013, 19:31:05 CEST »
0
Problema risolto, ho messo gli header esattamente come li mette Fiddler quando provo da un sito web via jQuery e funziona:

objPost.setHeader("Accept", "application/json, text/javascript, */*; q=0.01");
objPost.setHeader("Content-type", "application/json; charset=utf-8");   
objPost.setHeader("X-Requested-With", "XMLHttpRequest");
objPost.setHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)");

La cosa che non capisco è perche se ora rimetto gli header esattamente come erano prima continua a funzionare anche se cambio il web.config, ricompilo il progetto .NET, faccio ripartire da 0 Eclipse..mah... forse qualche cosa di caching che dovrei spegnere fisicamente tutto e forse non basta?...
Comunque se lascio tutto così funziona sempre.