【问题标题】:Server response / callback after Silverlight file uploadSilverlight 文件上传后的服务器响应/回调
【发布时间】:2010-04-01 13:45:15
【问题描述】:

好的,首先,独角兽头像很搞笑。说真的,我以为我的帐户被盗用了。愚人节快乐。

现在我正在通过 Silverlight 将文件上传到服务器。通知 Silverlight 文件已上传的最佳方式是什么?甚至可能会折腾其他信息,例如成功/失败等。

我的文件上传逻辑遵循了一个简单的教程here

【问题讨论】:

    标签: silverlight file-upload


    【解决方案1】:

    首先重写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 上传文件的“Id”怎么办?
    • @Matt:现在情况不同了,您还想从服务器取回数据。由于我还没有找到令人信服的论据,WebClient 不直接支持这种情况的原因。一个奇怪的设计选择恕我直言,但我知道。但是,可以将 WebClient 子类化以添加它。
    • @AnthonyWJones:嗯,我不打算做那么多努力。看起来我将只实施计划 B。我将首先使用 WCF 保存我的 Silverlight 对象,然后通过将 Id 传递给查询字符串来上传文件。然后我可以在两者之间建立关系。
    • @AnthonyWJones:如何使用上面的第二个代码块?我是否创建一个新的回调函数并将该代码放在那里?文件上传呢?
    • @AnthonyWJones:没关系,我现在明白了!但是,如果可以,请教我如何在出现错误时使用调度程序 Invoke?
    【解决方案2】:

    有一种方法可以在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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 2014-06-20
      • 1970-01-01
      相关资源
      最近更新 更多