【问题标题】:Xamarin.Forms Consume Rest ServiceXamarin.Forms 使用休息服务
【发布时间】:2018-10-27 04:11:55
【问题描述】:

我是 Xamarin 的新手,一般都在开发原生应用程序(我过去制作过 html5 应用程序)。 我已经开始了一个 Xamarin.Forms 项目,我正在尝试联系一个类似 API 的 REST(需要获取一个返回 json 数组的 URL)。

通常来自 C# 我会使用 RestSharp 并使用 RestClient 执行此调用。 虽然我没有从 Xamarin Studio 安装该软件包,但我已经安装了 Microsoft HTTP 库。

我很确定这是一项非常微不足道的任务,我只是无法调整我在网上找到的示例来为我工作。

请谁可以发布这是如何完成的(请记住我是新手,所以不要指望我理解与普通控制台应用程序不同的所有内容)?

【问题讨论】:

标签: rest xamarin xamarin.forms


【解决方案1】:

使用 HTTP 客户端和 JSON.NET 很容易,这里是一个 GET 示例:

public async Task<List<Appointment>> GetDayAppointments(DateTime day)
{
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + App.apiToken);
    //Your url.
    string resourceUri = ApiBaseAddress;

    HttpResponseMessage result = await client.GetAsync (resourceUri, CancellationToken.None);

    if (result.IsSuccessStatusCode) {
        try {
            return GetDayAppointmentsList(result);
        } catch (Exception ex) {
            Console.WriteLine (ex.Message);
        }
    } else {
        if(TokenExpired(result)){
            App.SessionExpired = true;
            App.ShowLogin();

        }
        return null;
    }

    return null;
}

private List<Appointment> GetDayAppointmentsList(HttpResponseMessage result){
    string content = result.Content.ReadAsStringAsync ().Result;
    JObject jresponse = JObject.Parse (content);

    var jarray = jresponse ["citas"];

    List<Appointment> AppoinmentsList = new List<Appointment> ();

    foreach (var jObj in jarray) {
        Appointment newApt = new Appointment ();

        newApt.Guid = (int)jObj ["id"];
        newApt.PatientId = (string)jObj ["paciente"];

        newApt.Name = (string)jObj ["nombre"];
        newApt.FatherLstName = (string)jObj ["paterno"];
        newApt.MotherLstName = (string)jObj ["materno"];

        string strStart = (string)jObj ["horaIni"];
        TimeSpan start;
        TimeSpan.TryParse (strStart, out start);
        newApt.StartDate = start;

        string strEnd = (string)jObj ["horaFin"];
        TimeSpan end;
        TimeSpan.TryParse (strEnd, out end);
        newApt.EndDate = end;

        AppoinmentsList.Add (newApt);
    }

    return AppoinmentsList;
}

【讨论】:

  • 我目前正在研究并尝试一些看起来有点像这样的东西。内部方法调用 GetDayAppointmentList 似乎是同步的,是因为它发生在已经异步的方法调用中,因此无论内部调用的性质如何,整体行为都因此变得异步?
  • Exactly GetDayAppointmentsList 无需等待,只需将代码分开并保持代码的可读性和可理解性。
【解决方案2】:

我使用 System.Net.WebClient 和我们的 asp.net WebAPI 接口:

    public string GetData(Uri uri)
{//uri like "https://webapi.main.cz/api/root"
  string ret = "ERROR";
  try
  {
    using (WebClient webClient = new WebClient())
    {
      //You can set webClient.Headers there
      webClient.Encoding = System.Text.Encoding.UTF8;
      ret = webClient.DownloadString(uri));//Test some data received
      //In ret you can have JSON string
    }
  }
  catch (Exception ex) { ret = ex.Message; }
  return ret;
}

4

 public string SendData(Uri uri, byte[] data)
{//uri like https://webapi.main.cz/api/PostCheckLicence/
  string ret = "ERROR";
  try
  {
    using (WebClient webClient = new WebClient())
    {
      webClient.Headers[HttpRequestHeader.Accept] = "application/octet-stream";
      webClient.Headers[HttpRequestHeader.ContentType] = "text/bytes";
      webClient.Encoding = System.Text.Encoding.ASCII;
      byte[] result = webClient.UploadData(uri, data);
      ret = Encoding.ASCII.GetString(result);
      if (ret.Contains("\"ResultWebApi\":\"OK"))
      {//In ret you can have JSON string
      }
      else
      {
      }
    }
  }
  catch (Exception ex) { ret = ex.Message; }
  return ret;
}

x

【讨论】:

  • 我可能错了,但这似乎是同步的。我知道我没有在帖子中提到这一点,但是在工作完成时不锁定应用程序必须是异步的。
  • 我的 WebAPI 使用自助服务,它在某一时刻管理一个查询和结果广播其他服务。在我们的例子中,这无关紧要。是的,在你的情况下异步可能会更好。
【解决方案3】:

我的 Github repo 中有一些示例。只需抓住那里的课程并尝试一下。该 API 非常易于使用:

await new Request<T>()
.SetHttpMethod(HttpMethod.[Post|Put|Get|Delete].Method) //Obligatory
.SetEndpoint("http://www.yourserver.com/profilepic/") //Obligatory
.SetJsonPayload(someJsonObject) //Optional if you're using Get or Delete, Obligatory if you're using Put or Post
.OnSuccess((serverResponse) => { 
   //Optional action triggered when you have a succesful 200 response from the server
  //serverResponse is of type T
})
.OnNoInternetConnection(() =>
{
    // Optional action triggered when you try to make a request without internet connetion
})
.OnRequestStarted(() =>
{
    // Optional action triggered always as soon as we start making the request i.e. very useful when
    // We want to start an UI related action such as showing a ProgressBar or a Spinner.
})
.OnRequestCompleted(() =>
{
    // Optional action triggered always when a request finishes, no matter if it finished successufully or
    // It failed. It's useful for when you need to finish some UI related action such as hiding a ProgressBar or
    // a Spinner.
})
.OnError((exception) =>
{
    // Optional action triggered always when something went wrong it can be caused by a server-side error, for
    // example a internal server error or for something in the callbacks, for example a NullPointerException.
})
.OnHttpError((httpErrorStatus) =>
{
    // Optional action triggered when something when sending a request, for example, the server returned a internal
    // server error, a bad request error, an unauthorize error, etc. The httpErrorStatus variable is the error code.
})
.OnBadRequest(() =>
{
    // Optional action triggered when the server returned a bad request error.
})
.OnUnauthorize(() =>
{
    // Optional action triggered when the server returned an unauthorize error.
})
.OnInternalServerError(() =>
{
    // Optional action triggered when the server returned an internal server error.
})
//AND THERE'S A LOT MORE OF CALLBACKS THAT YOU CAN HOOK OF, CHECK THE REQUEST CLASS TO MORE INFO.
.Start();

还有几个例子。

【讨论】:

    【解决方案4】:

    对于我所有的 Xamarin Forms 应用程序,我使用 Tiny.RestClient。 很容易得到,也很容易使用。

    你必须下载这个nuget

    之后就很容易使用了:

    var client = new TinyRestClient(new HttpClient(), "http://MyAPI.com/api");
    var cities = client.
    GetRequest("City").
    AddQueryParameter("id", 2).
    AddQueryParameter("country", "France").
    ExecuteAsync<City>> ();
    

    希望有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      相关资源
      最近更新 更多