Silverlight文件上传后的服务器响应/回调

3

首先,独角兽头像太搞笑了。说真的,我还以为我的账户被盗了。愚人节快乐。

现在我正在通过Silverlight将文件上传到服务器。如何最好地通知Silverlight文件已经上传?甚至可以返回其他信息,例如成功/失败等。

我按照一个简单的教程(这里)来编写我的文件上传逻辑。

2个回答

2
首先,将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();
    }

如果我想要回传上传文件的“Id”给Silverlight,该怎么做呢? - Matt
@Matt:啊,现在情况不同了,你想要从服务器获取数据。出于我尚未找到令人信服的理由,WebClient不直接支持该场景。在我看来,这是一个奇怪的设计选择,但我也不知道。然而,可能可以通过子类化WebClient来添加它。 - AnthonyWJones
@AnthonyWJones:没事了,我现在懂了!但是如果可以的话,您能教我如何在出现错误时使用调度程序Invoke吗? - VoodooChild
@Anthony data.Close(); 对我来说没有阻塞!?callback(null) 总是被调用。我的做法是在通用处理程序的处理请求部分抛出异常。 - gideon
callback(null) 应该放在 try 块之外。 - Quibblesome
显示剩余4条评论

1
使用Silverlight中的WebClient可以上传文件并获取服务器响应。
通过UploadStringAsync,内部将字符串转换为字节,并通过其编码进行转换:
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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接