Xamarin System.Json无法将JSON字符串解析为JsonValue对象

时间:2014-10-06 22:51:50

标签: c# xamarin.ios xamarin imgur

我在MacOSX上使用Xamarin Studio并处理iOS测试项目。

我正在发送一个Http请求将图像上传到Imgur,然后在完成时尝试解析响应。上传成功执行但是当我尝试解析字符串响应时,收到错误消息:

Unable to cast object of type 'System.Int32' to type 'System.String'

但我得到的JSON字符串如下:

{
  "data": {
    "id": "EGpAY43",
    "title": "adasd",
    "description": "eqeqwd",
    "datetime": 1412635648,
    "type": "image\/png",
    "animated": false,
    "width": 480,
    "height": 360,
    "size": 343319,
    "views": 0,
    "bandwidth": 0,
    "vote": null,
    "favorite": false,
    "nsfw": null,
    "section": null,
    "account_url": null,
    "deletehash": "qAXQgXXuAZ91sJS",
    "link": "http:\/\/i.imgur.com\/EGpAY43.png"
  },
  "success": true,
  "status": 200
}

正如您所看到的那样,这是一个正确的JSON字符串,但由于某种原因,我不明白它无法解析。

我用来上传图片的代码如下:

    protected async void UploadHandler(object sender, EventArgs e){
        var title = TitleTxt.Text;
        var description = DescriptionTxt.Text;
        var image = SelectionImg.Image;

        var imageBytes = image.AsPNG ().ToArray();

        string response = await UploadImage (title, description, imageBytes);

        try{
            var jsonResponse = JsonObject.Parse (response);
        }catch(Exception ex){
            Console.WriteLine ("Error " + ex.Message);
            Console.WriteLine ("Http Request response " + response);
        }
    }

    protected async Task<string> UploadImage(string title, string description, byte[] imageBytes){
        Console.WriteLine ("Upload image");
        var url = "https://api.imgur.com/3/image";
        WebRequest request = HttpWebRequest.Create (url);
        request.Headers.Add ("Authorization", "Client-ID " + clientId);
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";
        request.Timeout = 10000;

        Stream requestStream = request.GetRequestStream ();

        string parameters = "image=" + Convert.ToBase64String (imageBytes);
        parameters += "&" + "title=" + title;
        parameters += "&" + "description=" + description;

        byte[] byteParams = System.Text.Encoding.UTF8.GetBytes (parameters);
        requestStream.Write (byteParams, 0, byteParams.Length);
        requestStream.Close ();
        try{
            WebResponse response = await request.GetResponseAsync ();
            using (Stream responseStream = response.GetResponseStream()) {
                using (StreamReader sr = new StreamReader (responseStream)) {
                    string content = sr.ReadToEnd ();
                    Console.WriteLine (content);
                    return content;
                }
            }
        }catch(Exception ex){
            return ex.Message;
        }
    }

我在没有修改的情况下返回字符串值,或者我在代码中做错了什么?

编辑1

我在Android上尝试了这个并且在解析时也失败了,但是消息有点不同:

Cannot cast from source type to destination type

我使用的代码是相同的(你可以看到我没有使用平台特定的东西,因为这个代码我想在PCL中使用它。)

奇怪的是我尝试使用不同的代码上传它,解析没有失败。

我试过的代码是:

    protected void UploadImage(string title, string description, byte[] imageBytes){

        NameValueCollection postData = new NameValueCollection ();
        postData.Add ("image", Convert.ToBase64String(imageBytes));
        postData.Add ("title", title);
        postData.Add ("description", description);

        WebClient client = new WebClient ();
        client.Headers.Add ("Authorization", "Client-ID " + clientId);
        client.UploadValuesCompleted += new UploadValuesCompletedEventHandler(ReadStreamFromResponse);
        client.UploadValuesAsync (new Uri("https://api.imgur.com/3/image"), "POST", postData);
    }

    private void ReadStreamFromResponse(object sender, UploadValuesCompletedEventArgs e){
        string content = Encoding.Default.GetString (e.Result);
        try{
            // Parsing is done without problems
            var json = JsonObject.Parse (content);
        } catch(Exception ex){
            Console.WriteLine ("Error: " + ex.Message);
        }
    }

我不明白是什么问题,图片上传的Imgur响应无法在一个上解析,但在使用第二个代码时可以完成。

我猜这与我从响应中获取字节数组的方式有关。

什么可能导致这种行为?

编辑2

我对我的代码做了一些更改,我很困惑为什么一个实现正确分析而另一个没有。所以我试着让它能够在PCL中使用。我最终得到了这个:

我使用API​​ v3将图像上传到Imgur的功能:

    public async Task<WebResponse> UploadImage(byte[] imageBytes){
        // Since I'm making anonymous upload then I have no need of the other parameters
        // also some photos don't upload correctly with those perhaps something to do with what user L.B referred to me
        string parameters = Convert.ToBase64String (imageBytes);
        byte[] byteParams = System.Text.Encoding.UTF8.GetBytes (parameters);

        HttpWebRequest request = HttpWebRequest.CreateHttp ("https://api.imgur.com/3/image");

        request.Headers["Authorization"] = "Client-ID " + clientId;
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";


        using (var requestStream = await Task<Stream>.Factory.FromAsync (
                  request.BeginGetRequestStream,
                  request.EndGetRequestStream,
            (object)null)) {

            await requestStream.WriteAsync (byteParams, 0, byteParams.Length);
        }

        WebResponse response = await Task<WebResponse>.Factory.FromAsync (request.BeginGetResponse, request.EndGetResponse, request);
        return response;
    }

处理点击事件的方法:

    protected async void UploadClick(object sender, EventArgs e){
        // only focusing on upload the image
        BitmapDrawable drawable = (BitmapDrawable) selectedImg.Drawable;
        byte[] imageBytes;
        using (var stream = new MemoryStream ()) {
            Bitmap bitmap = drawable.Bitmap;
            bitmap.Compress (Bitmap.CompressFormat.Png, 0, stream);
            imageBytes = stream.ToArray ();
        }
        // wait for the response then pass it to ReadStreamFromResponse
        WebResponse response = await UploadImage (imageBytes);
        ReadStreamFromResponse (response);
    }

从WebResponse读取流的方法:

    private void ReadStreamFromResponse(WebResponse response){
        using (Stream responseStream = response.GetResponseStream ()) {
            using (StreamReader sr = new StreamReader (responseStream)) {
                string content = sr.ReadToEnd ();
                try{
                // This is parsed successfully
                    var json = JsonObject.Parse (content);

                } catch(Exception ex){
                    Console.WriteLine ("Error: " + ex.Message);
                }
            }
        }
    }

虽然此实现上传图像并正确解析,但我无法确定问题的根源。我需要识别它,以便我能理解我做错了什么,并在下次避免它。

0 个答案:

没有答案