• 重新想象 Windows 8 Store Apps (66)


    [源码下载]


    重新想象 Windows 8 Store Apps (66) - 后台任务: 下载和上传



    作者:webabcd


    介绍
    重新想象 Windows 8 Store Apps 之 后台任务

    • 后台下载任务
    • 后台上传任务



    示例
    扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知
    BackgroundTask/TransferModel.cs

    /*
     * 扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知
     */
    
    using System;
    using System.ComponentModel;
    using Windows.Networking.BackgroundTransfer;
    
    namespace XamlDemo.BackgroundTask
    {
        public class TransferModel : INotifyPropertyChanged
        {
            public DownloadOperation DownloadOperation { get; set; }
            public UploadOperation UploadOperation { get; set; }
    
            public string Source { get; set; }
            public string Destination { get; set; }
            
            private string _progress;
            public string Progress
            {
                get { return _progress; }
                set
                {
                    _progress = value;
                    RaisePropertyChanged("Progress");
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void RaisePropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
        }
    }


    1、演示后台下载任务的应用
    BackgroundTask/TransferDownload.xaml

    <Page
        x:Class="XamlDemo.BackgroundTask.TransferDownload"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.BackgroundTask"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <ScrollViewer Height="100">
                    <TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" />
                </ScrollViewer>
    
                <Button Name="btnAddDownload" Content="新增一个下载任务" Margin="0 10 0 0" Click="btnAddDownload_Click" />
                <Button Name="btnPause" Content="暂停所有下载任务" Margin="0 10 0 0" Click="btnPause_Click" />
                <Button Name="btnResume" Content="继续所有下载任务" Margin="0 10 0 0" Click="btnResume_Click" />
                <Button Name="btnCancel" Content="取消所有下载任务" Margin="0 10 0 0" Click="btnCancel_Click" />
    
                <ListView Name="listView" Padding="0 10 0 0" Height="300">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="0 5" Background="Blue">
                                <TextBlock Text="{Binding Source}" Margin="5" />
                                <TextBlock Text="{Binding Destination}" Margin="5" />
                                <TextBlock Text="{Binding Progress}" Margin="5" />
                            </StackPanel>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
                
            </StackPanel>
        </Grid>
    </Page>

    BackgroundTask/TransferDownload.xaml.cs

    /*
     * 演示后台下载任务的应用
     * 
     * BackgroundDownloader - 后台下载任务管理器
     *     CostPolicy - 下载的成本策略,BackgroundTransferCostPolicy 枚举
     *         Default - 允许在高成本(比如 2G 3G)网络上传输(默认值)
     *         UnrestrictedOnly - 不允许在高成本(比如 2G 3G)网络上传输
     *         Always - 无论如何均可传输,即使在漫游时
     *     ServerCredential - 与服务端通信时的凭据
     *     ProxyCredential - 使用代理时的身份凭据
     *     SetRequestHeader(string headerName, string headerValue) - 设置 http 请求头
     *     CreateDownload(Uri uri, IStorageFile resultFile) - 创建一个下载任务,返回 DownloadOperation 对象
     *     Group - 用于分组下载任务
     *     static GetCurrentDownloadsAsync(string group) - 获取指定组下的所有下载任务
     *     static GetCurrentDownloadsAsync() - 获取未与组关联的所有下载任务
     *     
     * DownloadOperation - 下载任务对象
     *     CostPolicy - 下载的成本策略,BackgroundTransferCostPolicy 枚举
     *     Group - 获取此下载任务的所属组
     *     Guid - 获取此下载任务的标识
     *     RequestedUri - 下载的源 URI
     *     ResultFile - 下载的目标文件
     *     GetResponseInformation() - 下载完成后获取到的服务端响应信息,返回 ResponseInformation 对象
     *         ActualUri - 下载源的真实 URI
     *         Headers - 服务端响应的 HTTP 头
     *         StatusCode - 服务端响应的状态码
     *     Pause() - 暂停此任务
     *     Resume() - 继续此任务
     *     StartAsync() - 新增一个下载任务,返回 IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> 对象
     *     AttachAsync() - 监视已存在的下载任务,返回 IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> 对象
     *     Progress - 获取下载进度,返回 BackgroundDownloadProgress 对象
     *     
     * BackgroundDownloadProgress - 后台下载任务的下载进度对象
     *     BytesReceived - 已下载的字节数
     *     TotalBytesToReceive - 总共需要下载的字节数,未知则为 0 
     *     Status - 下载状态,BackgroundTransferStatus 枚举
     *         Idle, Running, PausedByApplication, PausedCostedNetwork, PausedNoNetwork, Completed, Canceled, Error
     *     HasResponseChanged - 服务端响应了则为 true
     *     HasRestarted - 当下载连接断掉后,系统会通过 http range 头向服务端请求断点续传,如果服务端不支持断点续传则需要重新下载,此种情况则为 true
     */
    
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Linq;
    using Windows.Networking.BackgroundTransfer;
    using Windows.Storage;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.Web;
    
    namespace XamlDemo.BackgroundTask
    {
        public sealed partial class TransferDownload : Page
        {
            // 下载任务的集合
            private ObservableCollection<TransferModel> _transfers = new ObservableCollection<TransferModel>();
    
            // 所有下载任务的关联的 CancellationTokenSource 对象
            private CancellationTokenSource _cancelToken = new CancellationTokenSource();
           
            public TransferDownload()
            {
                this.InitializeComponent();
    
                Init();
            }
    
            private async void Init()
            {
                listView.ItemsSource = _transfers;
    
                // 获取全部下载任务
                await LoadDownloadAsync();
            }
    
            // 加载全部下载任务
            private async Task LoadDownloadAsync()
            {
                IReadOnlyList<DownloadOperation> downloads = null;
                try
                {
                    // 获取所有后台下载任务
                    downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                    return;
                }
    
                if (downloads.Count > 0)
                {
                    List<Task> tasks = new List<Task>();
                    foreach (DownloadOperation download in downloads)
                    {
                        // 监视指定的后台下载任务
                        tasks.Add(HandleDownloadAsync(download, false));
                    }
    
                    await Task.WhenAll(tasks);
                }
            }
    
            // 新增一个下载任务
            private async void btnAddDownload_Click(object sender, RoutedEventArgs e)
            {
                // 下载地址(注意需要在 Package.appxmanifest 中增加对 .rar 类型文件的关联)
                Uri sourceUri = new Uri("http://files.cnblogs.com/webabcd/Windows8.rar", UriKind.Absolute);
    
                StorageFile destinationFile;
                try
                {
                    // 保存的目标地址
                    destinationFile = await KnownFolders.DocumentsLibrary.CreateFileAsync("Windows8.rar", CreationCollisionOption.GenerateUniqueName);
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                    return;
                }
    
                // 创建一个后台下载任务
                BackgroundDownloader backgroundDownloader = new BackgroundDownloader();
                DownloadOperation download = backgroundDownloader.CreateDownload(sourceUri, destinationFile);
    
                // 监视指定的后台下载任务
                await HandleDownloadAsync(download, true);
            }
    
            /// <summary>
            /// 监视指定的后台下载任务
            /// </summary>
            /// <param name="download">后台下载任务</param>
            /// <param name="isNew">是否是新增的任务</param>
            private async Task HandleDownloadAsync(DownloadOperation download, bool isNew)
            {
                try
                {
                    // 将 DownloadOperation 附加到 TransferModel,以便下载进度可通知
                    TransferModel transfer = new TransferModel();
                    transfer.DownloadOperation = download;
                    transfer.Source = download.RequestedUri.ToString();
                    transfer.Destination = download.ResultFile.Path;
                    transfer.Progress = "0 / 0";
    
                    _transfers.Add(transfer);
    
                    lblMsg.Text += "Task Count: " + _transfers.Count.ToString();
                    lblMsg.Text += Environment.NewLine;
    
                    // 当下载进度发生变化时的回调函数
                    Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
    
                    if (isNew)
                        await download.StartAsync().AsTask(_cancelToken.Token, progressCallback); // 新增一个后台下载任务
                    else
                        await download.AttachAsync().AsTask(_cancelToken.Token, progressCallback); // 监视已存在的后台下载任务
    
                    // 下载完成后获取服务端的响应信息
                    ResponseInformation response = download.GetResponseInformation();
                    lblMsg.Text += "Completed: " + response.ActualUri + "-" + response.StatusCode.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
                catch (TaskCanceledException) // 调用 CancellationTokenSource.Cancel() 后会抛出此异常
                {
                    lblMsg.Text += "Canceled: " + download.Guid;
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    // 将异常转换为 WebErrorStatus 枚举,如果获取到的是 WebErrorStatus.Unknown 则说明此次异常不是涉及 web 的异常
                    WebErrorStatus error = BackgroundTransferError.GetStatus(ex.HResult);
    
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
                finally
                {
                    _transfers.Remove(_transfers.First(p => p.DownloadOperation == download));
                }
            }
    
            // 进度发生变化时,更新 TransferModel 的 Progress,以便通知
            private void DownloadProgress(DownloadOperation download)
            {
                TransferModel transfer = _transfers.First(p => p.DownloadOperation == download);
                transfer.Progress = download.Progress.BytesReceived.ToString("#,0") + " / " + download.Progress.TotalBytesToReceive.ToString("#,0");
            }
    
            // 暂停全部后台下载任务
            private void btnPause_Click(object sender, RoutedEventArgs e)
            {
                lblMsg.Text += "All Paused";
                lblMsg.Text += Environment.NewLine;
                foreach (TransferModel transfer in _transfers)
                {
                    if (transfer.DownloadOperation.Progress.Status == BackgroundTransferStatus.Running)
                    {
                        transfer.DownloadOperation.Pause();
                    }
                }
            }
    
            // 继续全部后台下载任务
            private void btnResume_Click(object sender, RoutedEventArgs e)
            {
                lblMsg.Text += "All Resumed";
                lblMsg.Text += Environment.NewLine;
                foreach (TransferModel transfer in _transfers)
                {
                    if (transfer.DownloadOperation.Progress.Status == BackgroundTransferStatus.PausedByApplication)
                    {
                        transfer.DownloadOperation.Resume();
                    }
                }
            }
    
            // 取消全部后台下载任务
            private void btnCancel_Click(object sender, RoutedEventArgs e)
            {
                _cancelToken.Cancel();
                _cancelToken.Dispose();
    
                _cancelToken = new CancellationTokenSource();
            }
        }
    }


    2、演示后台上传任务的应用
    BackgroundTask/TransferUpload.xaml

    <Page
        x:Class="XamlDemo.BackgroundTask.TransferUpload"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.BackgroundTask"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <ScrollViewer Height="100">
                    <TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" />
                </ScrollViewer>
    
                <Button Name="btnAddUpload" Content="新增一个上传任务(一次请求上传一个文件)" Margin="0 10 0 0" Click="btnAddUpload_Click" />
                <Button Name="btnAddMultiUpload" Content="新增一个上传任务(一次请求上传多个文件)" Margin="0 10 0 0" Click="btnAddMultiUpload_Click" />
                <Button Name="btnCancel" Content="取消所有上传任务" Margin="0 10 0 0" Click="btnCancel_Click" />
    
                <ListView Name="listView" Padding="0 10 0 0" Height="300">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="0 5" Background="Blue">
                                <TextBlock Text="{Binding Source}" Margin="5" />
                                <TextBlock Text="{Binding Destination}" Margin="5" />
                                <TextBlock Text="{Binding Progress}" Margin="5" />
                            </StackPanel>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
    
            </StackPanel>
        </Grid>
    </Page>

    BackgroundTask/TransferUpload.xaml.cs

    /*
     * 演示后台上传任务的应用
     * 
     * BackgroundUploader - 后台上传任务管理器
     *     CostPolicy - 上传的成本策略,BackgroundTransferCostPolicy 枚举
     *         Default - 不允许在高成本(比如 2G 3G)网络上传输
     *         UnrestrictedOnly - 允许在高成本(比如 2G 3G)网络上传输
     *         Always - 无论如何均可传输,即使在漫游时
     *     ServerCredential - 与服务端通信时的凭据
     *     ProxyCredential - 使用代理时的身份凭据
     *     SetRequestHeader(string headerName, string headerValue) - 设置 http 请求头
     *     CreateUpload(Uri uri, IStorageFile sourceFile) - 创建一个上传任务,返回 UploadOperation 对象
     *     CreateUploadFromStreamAsync(Uri uri, IInputStream sourceStream) - 以流的方式创建一个上传任务
     *     CreateUploadAsync(Uri uri, IEnumerable<BackgroundTransferContentPart> parts) - 创建一个包含多个上传文件的上传任务
     *     Group - 用于分组上传任务
     *     static GetCurrentUploadsAsync(string group) - 获取指定组下的所有上传任务
     *     static GetCurrentUploadsAsync() - 获取未与组关联的所有上传任务
     *     
     * UploadOperation - 上传任务对象
     *     CostPolicy - 上传的成本策略,BackgroundTransferCostPolicy 枚举
     *     Group - 获取此上传任务的所属组
     *     Guid - 获取此上传任务的标识
     *     RequestedUri - 上传任务所请求的服务端地址
     *     SourceFile - 需要上传的文件,如果是一次上传多个文件则此属性为 null
     *     GetResponseInformation() - 上传完成后获取到的服务端响应信息,返回 ResponseInformation 对象
     *         ActualUri - 上传服务的真实 URI
     *         Headers - 服务端响应的 HTTP 头
     *         StatusCode - 服务端响应的状态码
     *     StartAsync() - 新增一个上传任务,返回 IAsyncOperationWithProgress<UploadOperation, UploadOperation> 对象
     *     AttachAsync() - 监视已存在的上传任务,返回 IAsyncOperationWithProgress<UploadOperation, UploadOperation> 对象
     *     Progress - 获取上传进度,返回 BackgroundUploadProgress 对象
     *     
     * BackgroundUploadProgress - 后台上传任务的上传进度对象
     *     BytesSent - 已上传的字节数
     *     TotalBytesToSend - 总共需要上传的字节数
     *     Status - 上传状态,BackgroundTransferStatus 枚举
     *         Idle, Running, PausedByApplication, PausedCostedNetwork, PausedNoNetwork, Completed, Canceled, Error
     *     HasResponseChanged - 服务端响应了则为 true
     *     HasRestarted - 当上传连接断掉后,系统会重新上传,此种情况则为 true
     */
    
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Windows.Networking.BackgroundTransfer;
    using Windows.Storage;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.Web;
    
    namespace XamlDemo.BackgroundTask
    {
        public sealed partial class TransferUpload : Page
        {
            // 上传任务的集合
            private ObservableCollection<TransferModel> _transfers = new ObservableCollection<TransferModel>();
    
            // 所有上传任务的关联的 CancellationTokenSource 对象
            private CancellationTokenSource _cancelToken = new CancellationTokenSource();
    
            public TransferUpload()
            {
                this.InitializeComponent();
                
                Init();
            }
    
            private async void Init()
            {
                listView.ItemsSource = _transfers;
    
                // 获取全部上传任务
                await LoadUploadAsync();
            }
    
            // 加载全部上传任务
            private async Task LoadUploadAsync()
            {
                IReadOnlyList<UploadOperation> uploads = null;
                try
                {
                    // 获取所有后台上传任务
                    uploads = await BackgroundUploader.GetCurrentUploadsAsync();
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                    return;
                }
    
                if (uploads.Count > 0)
                {
                    List<Task> tasks = new List<Task>();
                    foreach (UploadOperation upload in uploads)
                    {
                        // 监视指定的后台上传任务
                        tasks.Add(HandleUploadAsync(upload, false));
                    }
    
                    await Task.WhenAll(tasks);
                }
            }
    
            // 新增一个上传任务(一次请求上传一个文件)
            private async void btnAddUpload_Click(object sender, RoutedEventArgs e)
            {
                // 上传服务的地址
                Uri serverUri = new Uri("http://localhost:39629/UploadFile.aspx", UriKind.Absolute);
    
                StorageFile sourceFile;
                try
                {
                    // 文件源
                    sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                    return;
                }
    
                // 实例化 BackgroundUploader,并设置 http header
                BackgroundUploader backgroundUploader = new BackgroundUploader();
                backgroundUploader.SetRequestHeader("Filename", "Logo.png");
    
                // 创建一个后台上传任务,此任务包含一个上传文件
                UploadOperation upload = backgroundUploader.CreateUpload(serverUri, sourceFile);
    
                // 以流的方式创建一个后台上传任务
                // await backgroundUploader.CreateUploadFromStreamAsync(Uri uri, IInputStream sourceStream);
    
                // 监视指定的后台上传任务
                await HandleUploadAsync(upload, true);
            }
    
            // 新增一个上传任务(一次请求上传多个文件)
            private async void btnAddMultiUpload_Click(object sender, RoutedEventArgs e)
            {
                // 上传服务的地址
                Uri serverUri = new Uri("http://localhost:39629/UploadFile.aspx", UriKind.Absolute);
    
                // 需要上传的文件源集合
                List<StorageFile> sourceFiles = new List<StorageFile>();
                for (int i = 0; i < 3; i++)
                {
                    StorageFile sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));
                    sourceFiles.Add(sourceFile);
                }
    
                // 构造需要上传 BackgroundTransferContentPart 集合
                List<BackgroundTransferContentPart> contentParts = new List<BackgroundTransferContentPart>();
                for (int i = 0; i < sourceFiles.Count; i++)
                {
                    BackgroundTransferContentPart contentPart = new BackgroundTransferContentPart("File" + i, sourceFiles[i].Name);
                    contentPart.SetFile(sourceFiles[i]);
                    contentParts.Add(contentPart);
                }
    
                // 创建一个后台上传任务,此任务包含多个上传文件
                BackgroundUploader backgroundUploader = new BackgroundUploader();
                UploadOperation upload = await backgroundUploader.CreateUploadAsync(serverUri, contentParts);
    
                // 监视指定的后台上传任务
                await HandleUploadAsync(upload, true);
            }
    
            /// <summary>
            /// 监视指定的后台上传任务
            /// </summary>
            /// <param name="upload">后台上传任务</param>
            /// <param name="isNew">是否是新增的任务</param>
            private async Task HandleUploadAsync(UploadOperation upload, bool isNew)
            {
                try
                {
                    // 将 UploadOperation 附加到 TransferModel,以便上传进度可通知
                    TransferModel transfer = new TransferModel();
                    transfer.UploadOperation = upload;
                    transfer.Source = "多个文件";
                    transfer.Destination = upload.RequestedUri.ToString();
                    transfer.Progress = "0 / 0";
    
                    _transfers.Add(transfer);
    
                    lblMsg.Text += "Task Count: " + _transfers.Count.ToString();
                    lblMsg.Text += Environment.NewLine;
    
                    // 当上传进度发生变化时的回调函数
                    Progress<UploadOperation> progressCallback = new Progress<UploadOperation>(UploadProgress);
    
                    if (isNew)
                        await upload.StartAsync().AsTask(_cancelToken.Token, progressCallback); // 新增一个后台上传任务
                    else
                        await upload.AttachAsync().AsTask(_cancelToken.Token, progressCallback); // 监视已存在的后台上传任务
    
                    // 上传完成后获取服务端的响应信息
                    ResponseInformation response = upload.GetResponseInformation();
                    lblMsg.Text += "Completed: " + response.ActualUri + "-" + response.StatusCode.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
                catch (TaskCanceledException) // 调用 CancellationTokenSource.Cancel() 后会抛出此异常
                {
                    lblMsg.Text += "Canceled: " + upload.Guid;
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    // 将异常转换为 WebErrorStatus 枚举,如果获取到的是 WebErrorStatus.Unknown 则说明此次异常不是涉及 web 的异常
                    WebErrorStatus error = BackgroundTransferError.GetStatus(ex.HResult);
    
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
                finally
                {
                    _transfers.Remove(_transfers.First(p => p.UploadOperation == upload));
                }
            }
    
            // 进度发生变化时,更新 TransferModel 的 Progress,以便通知
            private void UploadProgress(UploadOperation upload)
            {
                TransferModel transfer = _transfers.First(p => p.UploadOperation == upload);
                transfer.Progress = upload.Progress.BytesSent.ToString("#,0") + " / " + upload.Progress.TotalBytesToSend.ToString("#,0");
            }
    
            // 取消全部后台上传任务
            private void btnCancel_Click(object sender, RoutedEventArgs e)
            {
                _cancelToken.Cancel();
                _cancelToken.Dispose();
    
                _cancelToken = new CancellationTokenSource();
            }
        }
    }

    用于接收上传文件的服务
    WebServer/UploadFile.aspx.cs

    /*
     * 用于接收上传文件的服务
     */
    
    using System;
    using System.IO;
    
    namespace WebServer
    {
        public partial class UploadFile : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                try
                {
                    if (Request.Headers["Filename"] != null)
                    {
                        // 接收单个文件,并保存
                        string fileName = Request.Headers["Filename"];
                        string saveLocation = Server.MapPath("UploadFiles") + "\" + fileName.Insert(fileName.IndexOf("."), "_" + Guid.NewGuid().ToString());
                        using (System.IO.FileStream fs = new System.IO.FileStream(saveLocation, FileMode.Create))
                        {
                            Request.InputStream.CopyTo(fs);
                        }
                    }
                    else
                    {
                        // 接收多个文件,并保存
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            var file = Request.Files[i];
                            if (file.ContentLength > 0)
                            {
                                string fileName = System.IO.Path.GetFileName(file.FileName);
                                string saveLocation = Server.MapPath("UploadFiles") + "\" + fileName.Insert(fileName.IndexOf("."), "_" + Guid.NewGuid().ToString());
                                file.SaveAs(saveLocation);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.Write(ex.Message);
                    Response.StatusCode = 500;
                    Response.StatusDescription = ex.Message;
                    Response.End();
                }
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    C++中派生类使用基类成员的问题
    关于linux安装kettle的总结
    Servlet+JSP教程之:第一个Web程序
    Oracle开启和关闭的四种模式
    Android 图片设置圆角 方法之二
    Hive[6] HiveQL 查询
    JavaScript技巧45招
    JavaScript 权威指南第6版
    js 使用技巧
    Hive[5] HiveQL 数据操作
  • 原文地址:https://www.cnblogs.com/webabcd/p/3379890.html
Copyright © 2020-2023  润新知