当前位置: 首页 > 知识库问答 >
问题:

为PCL构建RESTful http客户端

姬飞飙
2023-03-14

上下文

最近,我开始使用Xamarin开发一个移动项目,它与C#/一起工作。NET.我来自开发Android应用和Java开发。当我在应用程序中构建超文本传输协议客户端时,我总是使用相同的方案。只有在必要的时候,我才喜欢压倒一切的概念。我想将JavaRESTful超文本传输协议客户端转换为C#/。NET RESTful超文本传输协议客户端。

我想要一个如下所示的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);
            }
        });
    }

我不想要一个具体的答案,或者一个完整的代码答案,只是被指出正确的方向。

共有1个答案

宗乐池
2023-03-14

这很简单,你想要的是一个流畅的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;
       }

    }
}
 类似资料:
  • 问题内容: 在我的文件中,我尝试实现一些映射,其中使用不同的分析器将属于一种类型的一个字段索引到其余字段。 目前,yaml文件具有以下结构: 这不会将自定义分析器应用于标题字段,因此我希望有人可以为我指出将自定义分析器应用于各个字段的正确方向? 问题答案: 我在ml中回答了这个问题: 如果您使用的是Java,则不必使用yml文件。您可以,但不必。 如果您使用的是Spring,则可以查看ES spr

  • 弗兰: 当尝试在VS2012中构建安装时(这甚至不涉及其他构建错误,但让我们从这里开始),我得到: 错误21错误C2228:“.serialize”的左侧必须具有class/struct/union D:\flann-1.8.4-src\flann-1.8.4-src\src\cpp\flann\util\serialization.h行18:type.serialize(ar);错误24错误LN

  • 创建客户端有两种方式,一种是直接使用特化的构造器函数,另一种是使用工厂构造器函数。 第一种方式返回的是具体的客户端结构体指针对象,第二种方式返回的是客户端接口对象。 使用特化的构造器函数创建客户端 特化的构造器函数有下面几个: func NewHTTPClient(uri ...string) (client *HTTPClient) func NewTCPClient(uri ...string

  • 本文向大家介绍基于Springboot2.0构建ES的多客户端,包括了基于Springboot2.0构建ES的多客户端的使用技巧和注意事项,需要的朋友参考一下 有时候我们操作es的时候会有一些特殊的需求,例如需要操作的index使用了不同的es服务器、用户名、密码、参数等,这个时候我们需要使用不同的es的客户端进行操作,但是我们又不希望拆分成多个项目进行使用,这个时候我们就需要在我们的配置中自己构

  • 我试图将Spring Boot应用程序配置为管理客户端,但在设置以下依赖项后无法构建: 我不知道为什么它有两个相同的RestTemplateBuilder... 如何解决这个问题?

  • 前面我们对基于 MINA 的服务端架构有了一个大体认识,现在我们看一下客户端的情况。客户端需要连接到一个服务端,发送消息并处理响应 客户端首先创建一个 IOConnector (用以连接 Socket 的 MINA Construct (构件)),开启一个服务器的绑定 在连接创建时,一个 Session 会被创建并关联到该连接 应用或者客户端写入 Session,导致数据在穿越 Filter Ch