【发布时间】:2010-04-01 13:45:15
【问题描述】:
好的,首先,独角兽头像很搞笑。说真的,我以为我的帐户被盗用了。愚人节快乐。
现在我正在通过 Silverlight 将文件上传到服务器。通知 Silverlight 文件已上传的最佳方式是什么?甚至可能会折腾其他信息,例如成功/失败等。
我的文件上传逻辑遵循了一个简单的教程here
【问题讨论】:
好的,首先,独角兽头像很搞笑。说真的,我以为我的帐户被盗用了。愚人节快乐。
现在我正在通过 Silverlight 将文件上传到服务器。通知 Silverlight 文件已上传的最佳方式是什么?甚至可能会折腾其他信息,例如成功/失败等。
我的文件上传逻辑遵循了一个简单的教程here
【问题讨论】:
首先重写UploadFile函数如下:-
private void UploadFile(string fileName, Stream data, Action<Exception> callback)
{
UriBuilder ub = new UriBuilder("http://localhost:3840/receiver.ashx");
ub.Query = string.Format("filename={0}", fileName);
WebClient c = new WebClient();
c.OpenWriteCompleted += (sender, e) =>
{
try
{
PushData(data, e.Result);
e.Result.Close();
data.Close(); // This blocks until the upload completes
callback(null);
}
catch (Exception er)
{
callback(er);
}
};
c.OpenWriteAsync(ub.Uri);
}
现在你可以像这样使用这个函数了:-
Stream data = new fi.OpenRead();
try
{
FileUpload(fi.Name, data, (err) =>
{
// Note if you want to fiddle with the UI use dispatcher Invoke here.
if (err == null)
{
// Success
}
else
{
// Fail do something with the err to disply why
}
});
}
catch
{
data.Dispose();
}
【讨论】:
有一种方法可以在Silverlight 中使用WebClient 上传文件并获取服务器响应。
UploadStringAsync 内部通过其 Encoding 将字符串转换为字节:
byte[] bytes = this.Encoding.GetBytes(data);
所以,我写了简单的base64编码包装器(只实现了我场景中实际使用的方法):
public class WebClientUploaderBase64Encoding : System.Text.Encoding
{
public override int GetMaxCharCount(int byteCount) {throw new NotImplementedException();}
public override int GetMaxByteCount(int charCount){throw new NotImplementedException();}
public override int GetCharCount(byte[] bytes, int index, int count){throw new NotImplementedException();}
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex){throw new NotImplementedException();}
public override int GetByteCount(char[] chars, int index, int count)
{
var data = System.Convert.FromBase64CharArray(chars, index, count);
return data.Length;
}
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
var data = System.Convert.FromBase64CharArray(chars, charIndex, charCount);
for (int index = 0; index < data.Length; ++index)
bytes[byteIndex + index] = data[index];
return data.Length;
}
public override string GetString(byte[] bytes, int start, int length)
{
return System.Convert.ToBase64String(bytes, start, length);
}
}
现在上传的样子:
private async Task UploadFile(byte[] data)
{
var client = new WebClient() {Encoding = new WebClientUploaderBase64Encoding()};
string base64EncodedData = client.Encoding.GetString(data, 0, data.Length);
var base64EncodedResult = await client.UploadStringTaskAsync("http://api/query", base64EncodedData);
var resultBytes = client.Encoding.GetBytes(base64EncodedResult);
var json = Encoding.UTF8.GetString(resultBytes);
}
【讨论】: