2016-05-12 7 views
-1

ContextAufbau einer RESTful HTTP-Client für einen PCL

Vor kurzem begann ich auf einem mobilen Projekt arbeiten Xamarin verwendet, die mit C# /. NET arbeitet. Ich kam von der Entwicklung von Android-Apps und Java-Entwicklung im Allgemeinen. Ich benutze immer das gleiche Schema, wenn ich den HTTP-Client in einer App erstellen, die this ist. Ich mag das Konzept des Überschreibens nur, wenn es notwendig ist. Ich möchte diesen Java-RESTful-HTTP-Client in einen C#/.NET-RESTful-HTTP-Client übersetzen.

Ich möchte eine API haben, die wie folgt aussieht:

await MakeGetRequest<List<Role>>(Constants.RolesEnpoint) 
      .OnSuccess((response) => 
      { 
       //Response which is of type List<Role> 
       ShowList(response); 
      }) 
      .OnError((exception) => 
      { 
       ShowErrorMessage("Unkown error:" + exception.Message); 
      }) 
      .OnInternatServerError(() => 
      { 
       ShowErrorMessage("The server explode"); 
      }); 

Und gut, vor allem das Problem, dass ich mit Blick ist, dass ich bin nicht wirklich sicher, wie diese Lambda-Rückrufe zu implementieren . Was ich bisher getan ist:

//<summary> 
    // Makes a get request and deserializes the result JSON as T class objects. 
    // Check https://forums.xamarin.com/discussion/22732/3-pcl-rest-functions-post-get-multipart 
    //</summary> 
    //<param name="endpoint">The endpoint name i.e. "/api/v1/feed"</param> 
    //<param name="auth">True if we want to seth the AUTH_TOKEN cookie. False otherwise.</param> 
    private async RequestTask<T> MakeGetRequest<T>(string endpoint, bool auth = true) 
    { 
     await new RequestTask<T>((rt) => 
     { 
      try 
      { 
       ValidateAuthToken(); 
       var request = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress, endpoint)); 
       SetHeaders(request); 
       if (string.IsNullOrEmpty(authToken)) 
       { 
        rt.OnAuthTokenError(); 
       } 
       request.Headers["Cookie"] = authToken; 
       request.Method = "GET"; 

       HttpWebResponse response = await request.GetResponseAsync(); 

       if (!response.StatusCode.Equals(HttpStatusCode.OK)) 
       { 
        rt.OnHttpError(response.StatusCode); 
        switch (response.StatusCode) 
        { 
         case HttpStatusCode.Forbidden: 
          rt.OnForbidden(); 
          break; 
         case HttpStatusCode.InternalServerError: 
          rt.OnInternalServerError(); 
          break; 
         case HttpStatusCode.RequestTimeout: 
          rt.OnRequestTimeout(); 
          break; 
         case HttpStatusCode.GatewayTimeout: 
          rt.OnGatewayTimeout(); 
          break; 
         case HttpStatusCode.NotFound: 
          rt.OnNotFound(); 
          break; 
         case HttpStatusCode.Unauthorized: 
          rt.OnUnauthorized(); 
          break; 
        } 
       } 

       var respStream = response.GetResponseStream(); 
       respStream.Flush(); 

       using (StreamReader sr = new StreamReader(respStream)) 
       { 
        //Need to return this response 
        string strContent = sr.ReadToEnd(); 
        respStream = null; 
        rt.OnSuccess(JsonConvert.DeserializeObject<T>(strContent, dateTimeConverter)); 
       } 
      } 
      catch (Exception e) 
      { 
       rt.OnError(e); 
      } 
     }); 
    } 

Ich habe keine konkrete Antwort will, oder eine Voll Code Antwort, in der richtigen Richtung gerade darauf ist aus.

+0

Nun, Sie brauchen nur drei Funktionen erwarten eine Aktion , speichern diese Aktionen lokal und rufen Sie dann im richtigen Moment, Ihr Name ist Agustin? – Gusman

+0

Hört sich gut an, könntest du einen kleinen Ausschnitt bereitstellen? Ich dachte die gleiche Lösung, aber zum Beispiel, in der Klasse, wo ich lokal speichern werde die 'Aktion ' wie ich das [BuilderObject] (http://www.javaworld.com/article/2074938/core-java /too-many-parameters-in-java-methods-part-3-builder-pattern.html). Mein Hauptproblem ist, wie man diese Lambda Callback Funktionen anruft/deklariert. Und ja, mein Name ist Agustin: P. – 4gus71n

+0

Auch um flüssig zu sprechen, müssen Ihre Funktionen dasselbe Objekt zurückgeben. – Gusman

Antwort

0

Es ist einfach, was Sie wollen fließend api ist, und es müssen einige Aktionen für sie, so etwas wie dieses annehmen:

public class RestClient 
{ 
    Action<HttpWebResponse> onSuccess; 
    Action<HttpWebResponse> onError; 
    Action<HttpWebResponse> onInternalServerError; 

    public RestClient OnSuccess(Action<HttpWebResponse> Handler) 
    { 
     onSuccess = Handler; 
     return this; 
    } 

    public RestClient OnError(Action<HttpWebResponse> Handler) 
    { 
     onError = Handler; 
     return this; 
    } 

    public RestClient OnInternalServerError(Action<HttpWebResponse> Handler) 
    { 
     onInternalServerError= Handler; 
     return this; 
    } 

    private async RequestTask<T> MakeGetRequest<T>(string endpoint, bool auth = true) 
    { 

     //lots of code, blablabla, just let's go on the handling 

     switch(response.StatusCode) 
     { 
      case HttpStatusCode.OK: 

       if(onSuccess != null) 
        onSuccess(response); 
       break; 

      case HttpStatusCode.InternalServerError: 

       if(onInternalServerError!= null) 
        onInternalServerError(response); 
       break; 

      default: 

       if(onError!= null) 
        onError(response); 
       break; 
     } 

    } 
} 
+0

Warum der Downvote? – Gusman

+0

Aufgrund Ihres Vorteils gegenüber Menschen, die kein Spanisch sprechen. – EZI

+0

welcher vorteil? die frage und die antwort ist auf englisch, was er gesagt hat ist nur die frage auf spanisch, also hat er mir keine weiteren hinweise gegeben als die bei der frage ... – Gusman

Verwandte Themen