Java 为PCL构建RESTful http客户端
上下文 最近,我开始使用Xamarin开发一个移动项目,它与C#/.NET一起工作。我是开发android应用程序和Java开发的。当我在一个应用程序中构建http客户端时,我总是使用相同的方案。我喜欢只在必要时才覆盖的概念。我想将这个Java RESTful http客户机转换为C#/.NET RESTful http客户机 我想要一个如下所示的API:Java 为PCL构建RESTful http客户端,java,c#,android,rest,Java,C#,Android,Rest,上下文 最近,我开始使用Xamarin开发一个移动项目,它与C#/.NET一起工作。我是开发android应用程序和Java开发的。当我在一个应用程序中构建http客户端时,我总是使用相同的方案。我喜欢只在必要时才覆盖的概念。我想将这个Java RESTful http客户机转换为C#/.NET RESTful http客户机 我想要一个如下所示的API: await MakeGetRequest<List<Role>>(Constants.RolesEnpoint)
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");
});
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;
}
}
}
等待MakeGetRequest(Constants.RolesEnpoint)
.OnSuccess((响应)=>
{
//属于列表类型的响应
展示名单(回应);
})
.OnError((例外)=>
{
错误消息(“未知错误:+exception.Message”);
})
.OnInternatServerError(()=>
{
发送错误消息(“服务器爆炸”);
});
我面临的主要问题是,我不确定如何实现这些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);
}
});
}
//
//发出get请求并将结果JSON反序列化为T类对象。
//检查https://forums.xamarin.com/discussion/22732/3-pcl-rest-functions-post-get-multipart
//
//端点名称,即“/api/v1/feed”
//如果要设置身份验证令牌cookie,则为True。否则就错了。
私有异步请求任务MakeGetRequest(字符串端点,bool auth=true)
{
等待新的请求任务((rt)=>
{
尝试
{
ValidateAuthToken();
var request=(HttpWebRequest)WebRequest.Create(新Uri(基地址,端点));
SetHeaders(请求);
if(string.IsNullOrEmpty(authToken))
{
rt.OnAuthTokenError();
}
request.Headers[“Cookie”]=authToken;
request.Method=“GET”;
HttpWebResponse=wait request.GetResponseAsync();
如果(!response.StatusCode.Equals(HttpStatusCode.OK))
{
rt.OnHttpError(响应状态码);
开关(响应状态代码)
{
案例HttpStatusCode。禁止:
反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义反义;
打破
案例HttpStatusCode.InternalServerError:
rt.OnInternalServerError();
打破
案例HttpStatusCode.RequestTimeout:
rt.OnRequestTimeout();
打破
案例HttpStatusCode.GatewayTimeout:
rt.OnGatewayTimeout();
打破
案例HttpStatusCode.NotFound:
rt.OnNotFound();
打破
案例HttpStatusCode。未经授权:
rt.未经授权的();
打破
}
}
var respStream=response.GetResponseStream();
respStream.Flush();
使用(StreamReader sr=新StreamReader(respStream))
{
//需要返回此响应
字符串strContent=sr.ReadToEnd();
respStream=null;
rt.OnSuccess(JsonConvert.DeserializeObject(strContent,dateTimeConverter));
}
}
捕获(例外e)
{
rt.OnError(e);
}
});
}
我不想要一个具体的答案,也不想要一个完整的代码答案,只需要指出正确的方向。很简单,你想要的是一个流畅的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");
});
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;
}
}
}
公共类RestClient
{
成功的行动;
起诉人;
对InternalServerError的操作;
公共RestClient OnSuccess(操作处理程序)
{
onSuccess=处理程序;
归还这个;
}
公共RestClient OnError(操作处理程序)
{
onError=处理程序;
归还这个;
}
公共RestClient OnInternalServerError(操作处理程序)
{
onInternalServerError=处理程序;
归还这个;
}
私有异步请求任务MakeGetRequest(字符串端点,bool auth=true)
{
//大量的代码,等等,让我们继续处理
开关(响应状态代码)
{
案例HttpStatusCode.OK:
if(onSuccess!=null)
成功(响应);
打破
案例HttpStatusCode.InternalServerError:
如果(onInternalServerError!=null)
onInternalServerError(响应);
打破
违约:
如果(onError!=null)
onError(响应);
打破
}
}
}
嗯,您只需要三个函数就可以执行一个操作,将这些操作存储在本地,然后在适当的时候调用它们。顺便问一下,您的名字是Agustin?听起来不错,您能提供一个小片段吗?我想到了相同的解决方案,但例如,在该类中,我将本地存储我如何创建的操作。我的主要问题是如何调用/声明lambda回调函数。是的,我的名字是Agustin:P。另外,为了流畅,你的函数必须返回相同的对象。因为你比不懂西班牙语的人有优势。什么优势?问题和答案都是英文的,他说的只是西班牙语的问题,所以他没有给我更多的提示,就像问题中的提示一样…@EZI加密了西班牙语?¬¬... 还有,如果你不知道他说了什么,为什么你认为这会给我带来任何好处?在他告诉我之前,我开始写答案