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?
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. –
Da Konstruktoren nicht async sein können, wrappen Sie den Aufruf 'loadcabinets();' in einen Task: 'Task.Run (async() => erwarten loadcabinets());'. –
Als Vorschlag verwenden Sie "ICommand" und führen Sie das aus. Frameworks wie MvvmCross, ReactiveUI, MvvmLight usw. verfügen bereits über einsatzbereite Implementierungen. – Cheesebaron