C# NET 4上的WCF流式文件传输

C# NET 4上的WCF流式文件传输,c#,.net,asp.net,wcf,wcf-streaming,C#,.net,Asp.net,Wcf,Wcf Streaming,我需要一个关于WCF流文件传输的好例子 我已经找到了一些,并尝试了他们,但帖子是旧的,我在.NET4和IIS7上工作,所以有一些问题 你能给我一个很好的最新例子吗。下面的答案详细介绍了将二进制数据发布到restful服务的一些技巧 下面的代码是如何编写RESTful WCF服务的示例,虽然并不完整,但确实给出了可以从何处开始的指示 示例服务,请注意,这不是生产就绪代码 [ServiceContract] [AspNetCompatibilityRequirements(Requirem

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

我已经找到了一些,并尝试了他们,但帖子是旧的,我在.NET4和IIS7上工作,所以有一些问题


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

下面的答案详细介绍了将二进制数据发布到restful服务的一些技巧

下面的代码是如何编写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);
        }
    }
}
[服务合同]
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
公共类文件服务
{
私有收入WebRequestContext m_请求;
私人支出网络响应文本m_响应;
[WebGet(UriTemplate=“{appName}/{id}?action={action}”)]
公共流GetFile(字符串appName、字符串id、字符串操作)
{
var repository=newfilerepository();
var response=WebOperationContext.Current.OutgoingResponse;
var result=repository.GetById(int.Parse(id));
if(action!=null&&action.Equals(“下载”,StringComparison.InvariantCultureIgnoreCase))
{
Add(“内容处置”,string.Format(“附件;文件名={0}”,result.Name));
}
Add(HttpResponseHeader.ContentType,result.ContentType);
添加(“X-Filename”,result.Name);
返回结果。内容;
}
[WebInvoke(UriTemplate=“{appName}”,Method=“POST”)]
public void Save(字符串appName,流文件内容)
{
尝试
{
如果(WebOperationContext.Current==null)抛出新的InvalidOperationException(“WebOperationContext为null”);
m_Request=WebOperationContext.Current.IncomingRequest;
m_Response=WebOperationContext.Current.OutgoingResponse;
var file=CreateFileResource(fileContent,appName);
如果(!FileIsValid(file))抛出新的WebFaultException(HttpStatusCode.BadRequest);
保存文件(文件);
SetStatusAsCreated(文件);
}
捕获(例外情况除外)
{
如果(例如GetType()==typeof(WebFaultException))抛出;
if(例如GetType().IsGenericType&&ex.GetType().GetGenericTypeDefinition()==typeof(WebFaultException))抛出;
抛出新的WebFaultException(“发生意外错误。”,HttpStatusCode.InternalServerError);
}
}
私有文件资源CreateFileResource(流文件内容,字符串appName)
{
var result=new FileResource();
fileContent.CopyTo(result.Content);
result.ApplicationName=appName;
result.Name=m_请求.Headers[“X-Filename”];
result.Location=@“C:\SomeFolder\”+result.Name;
result.ContentType=m_请求.Headers[HttpRequestHeader.ContentType]??this.GetContentType(result.Name);
result.dateupload=DateTime.Now;
返回结果;
}
私有字符串GetContentType(字符串文件名)
{
//这应该用某种形式的逻辑来代替,以确定正确的文件内容类型(即,使用注册表、扩展名、xml文件等)
返回“应用程序/八位字节流”;
}
私有bool FileIsValid(FileResource文件)
{
var validator=新的FileResourceValidator();
var clientHash=m_Request.Headers[HttpRequestHeader.ContentMd5];
返回validator.IsValid(文件,clientHash);
}
私有void保存文件(FileResource文件)
{
//这将把有关文件的元数据持久化到数据库中(即大小、文件名、文件位置等)
新建FileRepository().AddFile(文件);
}
私有void SetStatusAsCreated(文件资源文件)
{
var location=新Uri(m_Request.UriTemplateMatch.RequestUri.AbsoluteUri+“/”+file.Id);
m_响应。设置状态已创建(位置);
}
}
示例客户端,请注意,这不是生产就绪代码

[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);
        }
    }
}
//*********************************
//样本客户机
// *********************************
私有无效上载按钮\单击(对象发送者,事件参数e)
{
var uri=”http://dev-fileservice/SampleApplication"
var fullFilename=@“C:\somefile.txt”;
var fileContent=File.ReadAllBytes(fullFilename);
使用(var webClient=new webClient())
{
尝试
{
webClient.Proxy=null;
添加(HttpRequestHeader.ContentMd5,this.CalculateFileHash());
添加(“X-DaysToKeep”,DurationNumericUpDown.Value.ToString());
添加(“X-Filename”,Path.GetFileName(fullFilename));
上传数据(uri,“POST”,文件内容);
var fileUri=webClient.ResponseHeaders[HttpResponseHeader.Location];
Console.WriteLine(“可以在“+fileUri”下载文件);
}
捕获(例外情况除外)
{
var异常=例如消息;
}
}
}
私有字符串CalculateFileHash()
{
var hash=MD5.Create().ComputeHash(File.ReadAllBytes(@“C:\somefile.txt”);
var sb=新的StringBuilder();
for(int i=0;i