C# Xamarin Android Rest 调用 PCL 错误 "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."

C# Xamarin Android Rest call in PCL error "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."

我过去曾使用 SO 来帮助解决几个问题。但是,我找不到解决我已经苦苦挣扎了 2 天的问题。

我是菜鸟,请多多指教:)

我有一个使用 Xamarin Studio 创建的应用程序,目标是 Android。这是来自 Rest Api 的基本 GET 请求。它工作得很好,直到我意识到在 IOS 和 Windows 中创建相同的应用程序时我并没有帮助自己。一旦我将项目更改为使用 PCL,我就开始出现错误,主要是围绕我的 RestClient class(最初来自 http://www.codeproject.com/Tips/497123/How-to-make-REST-requests-with-Csharp

来自我的机器人应用 class:

    var apiUser = GetString(Resource.String.apiUser);
    var apiPass = GetString(Resource.String.apiPass);
    //Get token from API
    string token = authenticate(apiUser,apiPass);

    public static string authenticate(string apiUser, string apiPass)
    {
        Authentication Auth = new Authentication ();
        try
        {
            // set json by passing AuthenticationUrl as endpoint, returns json data
            var o = JObject.Parse(EntryRepository.getJson(PJTApiUrls.getAuthenticationUrl(apiUser,apiPass)));
            Auth.Token = (string)o["Token"];
            return Auth.Token;
        }
        catch (Exception e)
        {
            // Couldn't do stuff. Log the exception.
            // TODO possible timeout, try again, if fails again then return error message
            if (e.Message.Contains("400") || e.Message.Contains("401"))
            {
                string error = string.Format("Invalid credentials, please try again");
                return error;
            } else {
                string error = string.Format ("An error occurred: \r\n{0}", e.Message);
                return error;
            }
        }
    }

getAuthenticationUrl 获取 api URL。 这是 getJson(在 PCL 中):

    public static string getJson(string endpoint)
    {
        string apiurl = endpoint;
        var client = new _RestClient();
        client.EndPoint = apiurl;
        client.ContentType = "application/json";
        client.Method = HttpVerb.GET;
        //client.Method = HttpVerb.POST;
        client.PostData = "";
        //client.PostData = "{postData: value}";
        //client.PostData = "{'someValueToPost': 'The Value being Posted'}";
        var json = client._MakeRequestAsync();
        // to append parameters, pass them into make request:
        //var json = client.MakeRequest("?param=0");

        return json.ToString();
    }

对于 _RestClient class(在 PCL 中):

    public async Task<string> _MakeRequestAsync()
    {
        try {
            var request = _MakeRequestAsync ("");
            return await request;
        }
        catch (Exception e){
            return e.Message;
        }
    }

    public async Task<string> _MakeRequestAsync(string parameters)
    {
        var uri = new Uri(EndPoint + parameters);
        var request = WebRequest.Create(uri) as HttpWebRequest;

        using (var response = await request.GetResponseAsync () as HttpWebResponse) {
            var responseValue = string.Empty;

            if (response.StatusCode != HttpStatusCode.OK) {
                var message = String.Format ("Request failed. Received HTTP {0}", response.StatusCode);
                throw new Exception (message);
            }

            // grab the response
            using (var responseStream = await Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null)) {
            //using (var responseStream = response.GetResponseStream ()) {
                if (responseStream != null)
                    using (var reader = new StreamReader (responseStream)) {
                        responseValue = reader.ReadToEnd ();
                    }
            }

            return responseValue;
        }
    }

responseValue 为 returning null return 等待请求说 "Status = Waiting for activation" 我也有错误:"Unexpected character encountered while parsing value: S. Path '', line 0, position 0."

但如果 R​​estClient class 在 Droid 中(而不是共享 PCL)并且包含以下内容,则此方法有效:

    public string MakeRequest ()
    {
        return MakeRequest ("");
    }

    public string MakeRequest (string parameters)
    {
        var request = (HttpWebRequest)WebRequest.Create (EndPoint + parameters);

        request.Method = Method.ToString ();
        request.ContentLength = 0;
        request.ContentType = ContentType;

        if (!string.IsNullOrEmpty (PostData) && Method == HttpVerb.POST) {
            var bytes = Encoding.GetEncoding ("iso-8859-1").GetBytes (PostData);
            request.ContentLength = bytes.Length;

            using (var writeStream = request.GetRequestStream ()) {
                writeStream.Write (bytes, 0, bytes.Length);
            }
        }

        using (var response = (HttpWebResponse)request.GetResponse ()) {
            var responseValue = string.Empty;

            if (response.StatusCode != HttpStatusCode.OK) {
                var message = String.Format ("Request failed. Received HTTP {0}", response.StatusCode);
                throw new ApplicationException (message);
            }

            // grab the response
            using (var responseStream = response.GetResponseStream ()) {
                if (responseStream != null)
                    using (var reader = new StreamReader (responseStream)) {
                        responseValue = reader.ReadToEnd ();
                    }
            }

            return responseValue;
        }
    }

我想不通,感谢任何 help/guidance。如果我能澄清任何事情,请告诉我。

***** 更新 ***** 感谢 @milen-pavlov 迄今为止的帮助,这是我目前所在的位置:

在Android项目中:

        var apiUser = GetString(Resource.String.apiUser);
        var apiPass = GetString(Resource.String.apiPass);
        //Get token from API
        var token = await authenticate(apiUser,apiPass);

        lblOutput.Text = token;

调用(也在 Android 项目中):

    public static async Task<string> authenticate(string apiUser, string apiPass)
    {
        Authentication Auth = new Authentication ();
        try
        {
            // set json by passing AuthenticationUrl as endpoint, returns json data
            var o = JObject.Parse(await EntryRepository.getJson(PJTApiUrls.getAuthenticationUrl(apiUser,apiPass)));
            Auth.Token = (string)o["Token"];
            return Auth.Token;
        }
        catch (Exception e)
        {
            if (e.Message.Contains("400") || e.Message.Contains("401"))
            {
                string error = string.Format("Invalid credentials, please try again");
                return error;
            } else {
                string error = string.Format ("An error occurred: \r\n{0}", e.Message);
                return error;
            }
        }
    }

在 PCL 项目中调用 json class:

    public static async Task<string> getJson(string endpoint)
    {
        string apiurl = endpoint;
        var client = new _RestClient();
        client.EndPoint = apiurl;
        client.ContentType = "application/json";
        client.Method = HttpVerb.GET;
        client.PostData = "";
        var json = await client._MakeRequestAsync();

        return json;
    }

然后在 PCL 项目中调用 restclient class:

    public async Task<string> _MakeRequestAsync()
    {
        var request = _MakeRequestAsync ("");
        return await request;
    }

    public async Task<string> _MakeRequestAsync(string parameters) 
    {
        var uri = new Uri(EndPoint + parameters);
        using (var client = new HttpClient())
        {
            var response = await client.GetAsync(uri);
            return await response.Content.ReadAsAsync<string>();
        };
    }

结束result/error:

感谢任何指导!

可以改用HttpClient吗? 示例 Get 请求类似于:

        public async Task<string> _MakeRequestAsync(string parameters) 
        {
            var uri = new Uri(EndPoint + parameters);
            using (var client = new HttpClient())
            {
                var response = await client.GetAsync(uri);
                return await result.Content.ReadAsStringAsync();
            };
        }