如何在Silverlight中使用异步双向二进制上传和下载数据?
我目前使用的样本是: http://msdn.microsoft.com/en-us/library/system.net.webrequest.begingetresponse.aspx
但是样本以请求开头,我需要从上传开始。
我尝试过使用WebClient但是我无法按一个序列进行上传/下载:Bidirectional use of Webclient for binary
答案 0 :(得分:2)
我在Silverlight.RadFileUploader中由Handlers。(ASHX)同步.Telerik的组件与这些处理程序一起使用。
namespace MyNameSpace.Web
{
public class FileHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.User.Identity.IsAuthenticated)
{
string fileName = context.Request.QueryString.Get("fileName");
if (File.Exists(fileName))
{
context.Response.ContentType = MimeType(fileName);
context.Response.AddHeader("Content-Transfer-Encoding", "binary");
context.Response.WriteFile(fileName, 0, length);
}
}
}
我削减了大部分代码,但它提出了这个想法。 我使用处理程序播放音频文件和处理程序来下载音频文件。 Mimetype是非常重要的部分。你的标题也很重要。通过这种方式,你可以告诉你想做什么。
对于异步,此页面可能有所帮助。 http://msdn.microsoft.com/en-us/library/ms227433(v=vs.100).aspx
修改强>
以下处理程序文件从目录中读取文件"Top.jasper"
并将其写入回调方法。 (ar.IsCompleted)
参数的IsCompleted属性检查它是否已完成。
<%@ WebHandler Language="C#" CodeBehind="BDTest.ashx.cs" Class="AHBSBus.Web.Classes.BDTest" %>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.IO;
namespace AHBSBus.Web.Classes
{
/// <summary>
/// Summary description for BDTest
/// </summary>
public class BDTest : IHttpAsyncHandler
{
public bool IsReusable { get { return false; } }
public BDTest()
{
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
{
cb = new AsyncCallback((ar) =>
{
if (ar.IsCompleted)
{
var result = ar.AsyncState;
File.WriteAllBytes("c:\\new.jasper", (byte[])result);
}
});
extraData = File.ReadAllBytes("c:\\Top.jasper");
context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");
AsynchOperation asynch = new AsynchOperation(cb, context, extraData);
asynch.StartAsyncWork();
return asynch;
}
public void EndProcessRequest(IAsyncResult result)
{
}
public void ProcessRequest(HttpContext context)
{
var ctx=context;
}
}
class AsynchOperation : IAsyncResult
{
private bool _completed;
private Object _state;
private AsyncCallback _callback;
private HttpContext _context;
bool IAsyncResult.IsCompleted { get { return _completed; } }
WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
Object IAsyncResult.AsyncState { get { return _state; } }
bool IAsyncResult.CompletedSynchronously { get { return false; } }
public AsynchOperation(AsyncCallback callback, HttpContext context, Object state)
{
_callback = callback;
_context = context;
_state = state;
_completed = false;
}
public void StartAsyncWork()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);
}
private void StartAsyncTask(Object workItemState)
{
//You may modify _state object here
_context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");
_context.Response.Write("Hello World from Async Handler!");
_completed = true;
_callback(this);
}
}
}
我为双向通信提供SignalR
。
答案 1 :(得分:2)
AHSX是Go的方式,但要特别考虑超过4 MB的文件。
你需要做什么两件事:
服务器端:Ashx HttpHandler将处理收到的数据:
public class FileUpload:IHttpHandler { public void ProcessRequest(HttpContext context) { _httpContext = context;
if (context.Request.InputStream.Length == 0)
throw new ArgumentException("No file input");
try
{
// Method that will be populating parameters from HttpHandler Request.
GetQueryStringParameters();
string uploadFolder = _directory;
string tempFileName = _fileName + _tempExtension;
if (_firstChunk)
{
//// Delete temp file
if (File.Exists(@HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + tempFileName))
File.Delete(@HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + tempFileName);
//// Delete target file
if (File.Exists(@HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + _fileName))
File.Delete(@HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + _fileName);
}
using (FileStream fs = File.Open(@HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + tempFileName, FileMode.Append))
{
SaveFile(context.Request.InputStream, fs);
fs.Close();
}
if (_lastChunk)
{
File.Move(HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + tempFileName, HostingEnvironment.ApplicationPhysicalPath + "/" + uploadFolder + "/" + _fileName);
}
}
catch (Exception e)
{
// Todo
// Logger Exception
throw;
}
}
}
将调用它的Silverlight类:
公共类UploadFile {
public void Upload(Stream streamNewFile,string fileName,string dirOnServer =“”) { this.uploadMode = UploadMode.OpenStream;
this.destinationOnServer = dirOnServer;
this.fileStream = streamNewFile;
this.fileName = fileName;
this.dataLength = this.fileStream.Length;
long dataToSend = this.dataLength - this.dataSent;
bool isLastChunk = dataToSend <= this.chunkSize;
bool isFirstChunk = this.dataSent == 0;
string docType = "document";
var strCurrentHost = HtmlPage.Document.DocumentUri.ToString().Substring(0, HtmlPage.Document.DocumentUri.ToString().LastIndexOf('/'));
UriBuilder httpHandlerUrlBuilder = new UriBuilder(strCurrentHost + "/FileUpload.ashx");
httpHandlerUrlBuilder.Query = string.Format("{5}file={0}&offset={1}&last={2}&first={3}&docType={4}&destination={6}",
fileName, this.dataSent, isLastChunk, isFirstChunk, docType,
string.IsNullOrEmpty(httpHandlerUrlBuilder.Query) ? string.Empty : httpHandlerUrlBuilder.Query.Remove(0, 1) + "&", destinationOnServer);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(httpHandlerUrlBuilder.Uri);
webRequest.Method = "POST";
webRequest.BeginGetRequestStream(new AsyncCallback(this.WriteToStreamCallback), webRequest);
}
}