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