c# – 在.NET 4上进行WCF流式文件传输

我需要一个关于WCF流式文件传输的好例子.

我找到了几个并试过它们,但帖子很旧,我在.net 4和IIS 7上玩耍,所以有一些问题.

你能给我一个很好的,最新的例子吗?

解决方法

以下答案详细介绍了使用一些技术将二进制数据发布到一个宁静的服务.

> Post binary data to a RESTful application
> What is a good way to transfer binary data to a HTTP REST API service?
> Bad idea to transfer large payload using web services?

以下代码是您如何编写RESTful WCF服务的示例,并不是完整的,但它会告诉您可以从哪里开始.

示例服务,请注意,这不是生产就绪代码.

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class FileService
{
    private IncomingWebRequestContext m_Request;
    private OutgoingWebResponseContext m_Response;

    [WebGet(UriTemplate = "{appName}/{id}?action={action}")]
    public Stream GetFile(string appName,string id,string action)
    {
        var repository = new FileRepository();
        var response = WebOperationContext.Current.OutgoingResponse;
        var result = repository.GetById(int.Parse(id));

        if (action != null && action.Equals("download",StringComparison.InvariantCultureIgnoreCase))
        {
            response.Headers.Add("Content-disposition",string.Format("attachment; filename={0}",result.Name));
        }

        response.Headers.Add(HttpResponseHeader.ContentType,result.ContentType);
        response.Headers.Add("X-Filename",result.Name);

        return result.Content;
    }

    [WebInvoke(UriTemplate = "{appName}",Method = "POST")]
    public void Save(string appName,Stream fileContent)
    {
        try
        {
            if (WebOperationContext.Current == null) throw new InvalidOperationException("WebOperationContext is null.");

            m_Request = WebOperationContext.Current.IncomingRequest;
            m_Response = WebOperationContext.Current.OutgoingResponse;

            var file = CreateFileResource(fileContent,appName);

            if (!FileIsValid(file)) throw new WebFaultException(HttpStatusCode.BadRequest);

            SaveFile(file);

            SetStatusAsCreated(file);
        }
        catch (Exception ex)
        {
            if (ex.GetType() == typeof(WebFaultException)) throw;
            if (ex.GetType().IsGenericType && ex.GetType().GetGenericTypeDeFinition() == typeof(WebFaultException<>)) throw;

            throw new WebFaultException<string>("An unexpected error occurred.",HttpStatusCode.InternalServerError);
        }
    }

    private FileResource CreateFileResource(Stream fileContent,string appName)
    {
        var result = new FileResource();

        fileContent.copyTo(result.Content);
        result.ApplicationName = appName;
        result.Name = m_Request.Headers["X-Filename"];
        result.Location = @"C:\SomeFolder\" + result.Name;
        result.ContentType = m_Request.Headers[HttpRequestHeader.ContentType] ?? this.GetContentType(result.Name);
        result.DateUploaded = DateTime.Now;

        return result;
    }

    private string GetContentType(string filename)
    {
        // this should be replaced with some form of logic to determine the correct file content type (I.E.,use registry,extension,xml file,etc.,)
        return "application/octet-stream";
    }

    private bool FileIsValid(FileResource file)
    {
        var validator = new FileResourceValidator();
        var clientHash = m_Request.Headers[HttpRequestHeader.ContentMd5];

        return validator.IsValid(file,clientHash);
    }

    private void SaveFile(FileResource file)
    {
        // This will persist the Meta data about the file to a database (I.E.,size,filename,file location,etc)
        new FileRepository().AddFile(file);
    }

    private void SetStatusAsCreated(FileResource file)
    {
        var location = new Uri(m_Request.UriTemplateMatch.RequestUri.AbsoluteUri + "/" + file.Id);
        m_Response.SetStatusAsCreated(location);
    }
}

示例客户端,请注意这不是生产就绪代码.

// *********************************
// Sample Client
// *********************************
private void UploadButton_Click(object sender,EventArgs e)
{
    var uri = "http://dev-fileservice/SampleApplication"
    var fullFilename = @"C:\somefile.txt";
    var fileContent = File.ReadAllBytes(fullFilename);

    using (var webClient = new WebClient())
    {
        try
        {
            webClient.Proxy = null;
            webClient.Headers.Add(HttpRequestHeader.ContentMd5,this.Calculatefilehash());
            webClient.Headers.Add("X-DaysToKeep",DurationNumericupdown.Value.ToString());
            webClient.Headers.Add("X-Filename",Path.GetFileName(fullFilename));
            webClient.UploadData(uri,"POST",fileContent);

            var fileUri = webClient.ResponseHeaders[HttpResponseHeader.Location];
            Console.WriteLine("File can be downloaded at" + fileUri);
        }
        catch (Exception ex)
        {
            var exception = ex.Message;
        }
    }
}

private string Calculatefilehash()
{
    var hash = MD5.Create().ComputeHash(File.ReadAllBytes(@"C:\somefile.txt"));
    var sb = new StringBuilder();

    for (int i = 0; i < hash.Length; i++)
    {
        sb.Append(hash[i].ToString("x2"));
    }

    return sb.ToString();
}

private void DownloadFile()
{
    var uri = "http://dev-fileservice/SampleApplication/1" // this is the URL returned by the Restful file service

    using (var webClient = new WebClient())
    {
        try
        {
            webClient.Proxy = null;
            var fileContent = webClient.DownloadData(uri);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...