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

原文: 重新想象 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
[源码下载]

你可能感兴趣的:(windows)