2017-05-01 7 views
0

Zuerst möchte ich sagen, dass ich immer wieder gelesen habe https://developer.xamarin.com/guides/xamarin-forms/cloud-services/consuming/rest/ Führer, aber es hilft nicht.Xamarin HttpClient wie man json holt und es benutzt

Ich habe einen phpwebservice die json zurückgibt, wenn gefragt:

<?php 

include("../include/class.pdogsb.inc.php"); 


$pdo = PdoGsb::getPdoGsb(); 


$tabCabinets = $pdo->getLesCabinets(); 



    header('Content-type: application/json'); 
    echo json_encode(array('cabinets'=>$tabCabinets)); 

?> 

es gibt eine Antwort dieser Art

cabinets": [ 

    { 
     "0": "1", 
     "1": "2,2891506", 
     "2": "48,8618687", 
     "3": "75016", 
     "4": "Paris", 
     "5": "1 Avenue Gustave V de Suède", 
     "id": "1", 
     "longitudeGPS": "2,2891506", 
     "latitudeGPS": "48,8618687", 
     "cp": "75016", 
     "ville": "Paris", 
     "rue": "1 Avenue Gustave V de Suède" 
    }, 

In meinem Xamarin PCL-Projekt habe ich eine Methode erstellt haben, die ich benutze, wenn ich Laden Sie meine Ansicht, um diese JSON-Daten zu holen.

using Newtonsoft.Json; 
    using suivAAndroid.Models; 
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Linq; 
    using System.Net.Http; 
    using System.Text; 
    using System.Threading.Tasks; 

    namespace suivAAndroid.ViewModel 
    { 
     public partial class CreerVisiteViewModel : INotifyPropertyChanged 
     { 
      #region propriétés 
      private Cabinet unCabinet; 
      private Medecin unMedecin; 

      public event PropertyChangedEventHandler PropertyChanged; 

      #endregion 

      #region methods 
      public CreerVisiteViewModel() 
      { 
       loadcabinets(); 
      } 
      private async Task loadcabinets() 
      { 
       List<Cabinet> listeCabinets = null; 
       HttpClient clientCabinets = new HttpClient(); 
       string url = "http://10.0.0.5/ppe3JoJuAd/gsbAppliFraisV2/webservices/w_cabinet.php"; 
//does not read the code after this line 
       var response = await clientCabinets.GetAsync(new Uri(url)); 
       string jsonString = await response.Content.ReadAsStringAsync(); 
       listeCabinets = JsonConvert.DeserializeObject<List<Cabinet>>(jsonString); 
      } 

      #endregion 
     } 
    } 

Mein Problem ist, während der Ausführung und Debuggen der Anwendung, wird der Compiler gehen nicht nach dem string url = "10.0.0.5/ppe3JoJuAd/gsbAppliFraisV2/webservices/w_cabinet.php"; Linie. Stattdessen kehrt es zu loadcabinets(); zurück, was bedeutet, dass der Client niemals die JSON-Daten holt.

was kann ich tun?

Edit: Aktualisiert Code mit den letzten Antworten

ich ein BaseViewModel erstellt, wo ich die ICommand Schnittstelle implementiert

public class RelayCommandAsync : ICommand 
    { 
     private Func<object, Task> _action; 
     private Task _task; 

     public RelayCommandAsync(Func<object, Task> action) 
     { 
      _action = action; 
     } 

     public bool CanExecute(object parameter) 
     { 
      return _task == null || _task.IsCompleted; 
     } 

     public event EventHandler CanExecuteChanged; 

     public async void Execute(object parameter) 
     { 
      _task = _action(parameter); 
      OnCanExecuteChanged(); 
      //await _task; 
      //OnCanExecuteChanged(); 
     } 

     private void OnCanExecuteChanged() 
     { 
      var handler = this.CanExecuteChanged; 
      if (handler != null) 
       handler(this, EventArgs.Empty); 
     } 
    } 

Hier ist das Ergebnis in meinem vorherigen Ansichtsmodell

#region methods 
     public CreerVisiteViewModel() 
     { 


     } 
     #endregion 
     #region Methods 
     public async Task<List<Cabinet>> loadcabinetsAsync() 
     { 
      List<Cabinet> listeCabinets = null; 
      HttpClient clientCabinets = new HttpClient(); 
      try 
      { 
       string url = "http://10.0.0.5/ppe3JoJuAd/gsbAppliFraisV2/webservices/w_cabinet.php"; 
       var uri = new Uri(string.Format(url, string.Empty)); 
       var response = await clientCabinets.GetAsync(uri); 
       string jsonString = await response.Content.ReadAsStringAsync(); 
       listeCabinets = JsonConvert.DeserializeObject<List<Cabinet>>(jsonString); 

      } 
      catch (Exception e) 
      { 

      } 
      return listeCabinets; 
     } 
     #endregion 


     #region ICommand 
     public ICommand ExecuteLoadCabinetAsync { get { return new RelayCommandAsync(x => loadcabinetsAsync()); } } 
     #endregion 

Es tut noch Lösen Sie nicht mein Problem mit dem Compiler, der nicht den ganzen Code der Methode liest, was kann ich mehr tun?

Antwort

1

Es gibt einige Probleme hier:

  1. Sie sind ein Asynchron-Methode aufrufen, ohne sie zu warten.
  2. Sie sind ein Asynchron-Methode in einem Konstruktor aufrufen
  3. Sie sind mehrere async Methoden direkt nach dem anderen anrufen, ohne ConfigureAwait (false) zu verwenden, können Sie Kontext wechseln wieder Sinn und her
  4. Ihre URL haben keine gültige Schema, so dass Sie wahrscheinlich eine Ausnahme gibt

Wenn Sie verwenden möchten, das MVVM Muster bekommen, würden Sie Ihren Code in ICommand wickeln, und führen Sie diesen Befehl, eine ObservableCollection zu füllen. Die Ausführung dieses Befehls würde in einem Lifecycle-Ereignis Ihrer ViewController/Activity/Page erfolgen, abhängig davon, auf welcher Plattform Sie sich befinden.

+0

Wie kann ich 1 und 2 auflösen? Ich wusste nicht 3. In der Tat hatte ich eine ungültige URI-Ausnahme geworfen, die ich löste, indem ich http vor die ganze Zeichenfolge setzte. –

+0

Da Konstruktoren nicht async sein können, wrappen Sie den Aufruf 'loadcabinets();' in einen Task: 'Task.Run (async() => erwarten loadcabinets());'. –

+0

Als Vorschlag verwenden Sie "ICommand" und führen Sie das aus. Frameworks wie MvvmCross, ReactiveUI, MvvmLight usw. verfügen bereits über einsatzbereite Implementierungen. – Cheesebaron