上下文
最近我开始使用Xamarin开发移动项目,该项目与C#/ .NET一起使用。我来自开发Android应用程序和Java开发。当我在this的应用程序中构建http客户端时,我总是使用相同的方案。我喜欢只有在必要时才重写的概念。我想将这个Java RESTful http客户端转换为C#/ .NET RESTful http客户端。
我想要一个看起来像这样的API:
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");
});
而且,主要是我面临的问题是我不确定如何实现这些lambda回调。到目前为止我所做的是:
//<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);
}
});
}
我不想要一个具体的答案,或者一个完整的代码答案,只是指出正确的方向。
答案 0 :(得分:0)
这很容易,你想要的是一个流畅的api,它必须接受一些动作,如下:
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;
}
}
}