File Upload功能

从用户方通过OpenFileDialog对象来得到图片内容.

使用BrowserHttpWebRequest 和 HttpWebResponse 对象来调用Web service .

要求 (available from the Silverlight download site):

Microsoft Silverlight 1.1 Alpha.

Microsoft Visual Studio Code Name "Orcas" Beta 1.

Microsoft Silverlight Tools Alpha for Visual Studio Code Name "Orcas" Beta 1.

An ASP.NET Web site.

A Silverlight project. See How to: Create a Silverlight Project for instructions.

使用OpenFileDialog 对象来得到图象文件
由于一些安全的考虑,你不能在浏览器端的代码中直接访问客户的文件系统.你可以使用isolated storage来得到和保存application文件. (For more information, see 在.NET Framework Silverlight中怎么样使用Isolated Storage .) 然而,对于一些情况下,你可能需要得到客户端的某些文件,你可以使用OpenFileDialog 对象来提示用户,用户再选择一个你的 application 可以正确访问的文件. 默认情况下,你只有对文件的只读权限,但实际用户可以在选择文件的同时来选择是否打开写权限.

想要与用户进行这些方面的交互, 创建一个OpenFileDialog object的实例, 设置对象的一些属性,比如 Title 和 Filter属性,然后调用ShowDialog 方法. 如果用户选择了一个文件(或多个)然后点击 OK, 那么 ShowDialog方法将返回一个值为OK的DialogResult对象 , 然后你可以访问这些文件了. 你通过OpenFileDialog object的SelectedFile property来访问用户选择的文件 . (如果你设置了OpenFileDialog object的EnableMultipleSelection 属性为true的话, 你就可以通过SelectedFiles property来访问多个文件了.) 你可以使用SelectedFile的 OpenText 或者 OpenRead 方法以流的方式来访问文件内容.

以下的示例将演示使用OpenFileDialog object来得到用户提供的image文件. 因为image 文件是二进制文件, 所以 OpenRead 方法以流的方式来访问该文件内容.然后内容被编码为 Base64串然后通过Web service 来传回到服务器.

CS

  
    
private void OnUpload( object sender, EventArgs e){ // Rehide the status canvas with each request. StatusCanvas.Visibility = Visibility.Hidden; // Prompt the user to select an image file. OpenFileDialog ofd = new OpenFileDialog();ofd.EnableMultipleSelection = false ;ofd.Filter = " Image files (*.jpg;*.png)|*.jpg;*.png " ;ofd.Title = " Select an image to upload " ; if (ofd.ShowDialog() == DialogResult.OK){ // Read the contents of the file. string fileName = ofd.SelectedFile.Name;Stream f = ofd.SelectedFile.OpenRead(); byte [] fileBytes = new byte [f.Length]; int byteCount = f.Read(fileBytes, 0 , ( int )f.Length); string fileContents = Convert.ToBase64String(fileBytes); // Post the file contents to the web service. UploadImage(fileName, fileContents); // Print the status of the upload. ResponseMessage.Foreground = new SolidColorBrush(Color.FromRgb( 0 , 0 , 255 ));StatusCanvas.Visibility = Visibility.Visible; // Display the uploaded image. UploadedImage.Source = new Uri( " GetImage.aspx?fileName= " + fileName, UriKind.Relative);}}

VB

  
    
Private Sub OnUpload(ByVal o As Object, ByVal e As EventArgs) ' Rehide the status canvas with each request. StatusCanvas.Visibility = Visibility.Hidden ' Prompt the user to select an image file. Dim ofd As New OpenFileDialog()ofd.EnableMultipleSelection = Falseofd.Filter = " Image files (*.jpg;*.png)|*.jpg;*.png " ofd.Title = " Select an image to upload " If ofd.ShowDialog() = DialogResult.OK Then ' Read the contents of the file. Dim fileName As String = ofd.SelectedFile.NameDim f As Stream = ofd.SelectedFile.OpenRead()Dim fileBytes(f.Length) As ByteDim byteCount As Integer = f.Read(fileBytes, 0 , CInt(f.Length))Dim fileContents As String = Convert.ToBase64String(fileBytes) ' Post the file contents to the web service. UploadImage(fileName, fileContents) ' Print the status of the upload. ResponseMessage.Foreground = New SolidColorBrush(Color.FromRgb( 0 , 0 , 255 ))StatusCanvas.Visibility = Visibility.Visible ' Display the uploaded image. UploadedImage.Source = _New Uri( " GetImage.aspx?fileName= " & fileName, UriKind.Relative)End IfEnd Sub



调用 Web Service 来 Upload 一个 Image 文件
你可以在Silverlight中使用HTTP POST来调用一个Web servic. 你可以使用BrowserHttpWebRequest object来创建一个 HTTP request.想要在 HTTP POST request中包含文件内容, 你可以先对二进制文件进行Base64 编码,然后包含他们到HTTP POST request的 body里 . 在这个示例中, HTTP POST request的 body 已经是 URL-encoded (例如, var1=value1&var2=value2&var3=value3).你可以把文件内容和文件名分别URL-encoded 为两个变量,像这种形式fileName=<image file name>&fileContents=<encoded file contents>, 如下.

CS

  
    
public void Page_Loaded( object o, EventArgs e){ // Required to initialize variables InitializeComponent();StatusCanvas.Visibility = Visibility.Hidden;UploadButton.MouseLeftButtonDown += OnUpload;}

 

VB

  
    
Public Sub Page_Loaded(ByVal o As Object, ByVal e As EventArgs) ' Required to initialize variables InitializeComponent()StatusCanvas.Visibility = Visibility.HiddenAddHandler UploadButton.MouseLeftButtonDown, AddressOf OnUploadEnd Sub



你可能会用到 HTTP POST来调用Web services . 想要在你的application中开启HTTP POST调用 Web services , 添加 HttpPost 到配置文件system.web里的 webServices configuration 区域中, 如下.

<system.web>
<webServices>
<protocols>
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>想了解更多如何在Silverlight中调用Web service , 查看 在Silverlight中怎么样使用代理来调用ASP.NET Web Service.

编译代码
你可以把以下代码拷贝一份到本地来运行.

创建ASP.NET Web Service
本篇QuickStart 示例使用 Web service 来接收一个uploaded file 内容. 因为安全的因素, 跨域调用是不允许的. 所以, .NET Framework for Silverlight 代码目前只能调用本域内的 Web service请求. 现在, 你必须创建一个站点,来包含 Silverlight client 页和Web service.

下面的Web service以包含要上传文件的路径为输入参数,然后返回一个image file 名称列表. 这么做是因为运行在browser中的 Silverlight client code 不需要直接访问Web server上的文件系统 .

开始创建ASP.NET Web service(不译,其实就是把内容放在CACHE中,然后又把内容写到客户端去,给用户看)
In Visual Studio, on the File menu, click New Web Site.

In the Visual Studio Installed Templates panel, click ASP.NET Web Service.

In the Location list, click File System. Specify a file path for your Web site, and then click OK.

-or-

You can click HTTP and create a new Web site on an Internet Information Services (IIS) Web server to host this sample.

Visual Studio will create an ASP.NET Web site with a default Web service.

双击 the Service.asmx file to edit it. Change class="Service" to class="SampleUploadServiceVB" for Visual Basic or class="SampleUploadServiceCS" for C#. Save the changes and close the file.

In the App_Code folder, 双击 the Service.cs or Service.vb file, depending on the programming language (Visual Basic or C#) you chose for your sample. Replace the contents of the file with the following code for your programming language.

App_Code

  
    
using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Web.Caching; using System.IO;[WebService(Namespace = " http://tempuri.org/ " )] public class SampleUploadServiceCS : System.Web.Services.WebService{ public SampleUploadServiceCS (){}

[WebMethod]

  
    
public void UploadImage( string fileName, string fileContents){ string imagePath = fileName;HttpContext.Current.Cache.Add(fileName, fileContents, null , DateTime.Now.AddSeconds( 30 ), TimeSpan.Zero,CacheItemPriority.High, null );}}



App_Code

  
    
Imports SystemImports System.WebImports System.Web.ServicesImports System.Web.Services.ProtocolsImports System.Web.CachingImports System.IO < WebService(Namespace: = " http:'tempuri.org/ " ) > _Public Class SampleUploadServiceVBInherits WebServicePublic Sub New()End Sub < WebMethod() > _Public Sub UploadImage(ByVal fileName As String, ByVal fileContents As String)Dim imagePath As String = fileNameHttpContext.Current.Cache.Add(fileName, fileContents, _Nothing, DateTime.Now.AddSeconds( 30 ), TimeSpan.Zero, _CacheItemPriority.High, Nothing)End SubEnd Class


Save the changes and close the file.

This sample does not write any files to the Web server file system. The Web service places the encoded file contents in the Cache for only 30 seconds so that the sample application can request them after they have been uploaded. To serve up the contents of the uploaded image file from the Cache, this sample uses an ASP.NET page that writes out the file stream using the BinaryWrite method.

右键单击 the Web site project, and click Add New Item.

Click Web Form. In the Name field, type GetImage.aspx. In the Language list, select the language that you prefer.

双击 the GetImage.aspx file to edit its contents. Replace the default contents with the following code for your preferred language.

VB

  
    
<% @ Page Language = " VB " AutoEventWireup = " true " CodeFile = " GetImage.aspx.vb " Inherits = " GetImage " %>



Save the changes and close the file.

双击 the GetImage.aspx.vb file for Visual Basic or the GetImage.aspx.cs file for C# to edit its contents. Replace the default contents with the following code for your preferred language.

CS

  
    
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.IO; using System.Text; public partial class GetImage : System.Web.UI.Page{ protected void Page_Load( object sender, EventArgs e){ string fileName = Request.QueryString[ " fileName " ]; string [] tmp = fileName.Split( ' . ' ); string extension = tmp[tmp.Length - 1 ]; switch (extension){ case " jpg " :Response.ContentType = " image/jpeg " ; break ; case " png " :Response.ContentType = " image/png " ; break ; default :Response.ContentType = " image/jpg " ; break ;} string fileContents = ( string )Cache[fileName];Response.BinaryWrite(Convert.FromBase64String(fileContents));}}



VB

  
    
Imports SystemImports System.DataImports System.ConfigurationImports System.CollectionsImports System.WebImports System.Web.SecurityImports System.Web.UIImports System.Web.UI.WebControlsImports System.Web.UI.WebControls.WebPartsImports System.Web.UI.HtmlControlsImports System.IOImports System.TextPartial Public Class GetImageInherits System.Web.UI.PageProtected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)Dim fileName As String = Request.QueryString( " fileName " )Dim tmp As String() = fileName.Split( " . " )Dim extension As String = tmp(tmp.Length - 1 )Select Case extensionCase " jpg " Response.ContentType = " image/jpeg " Case " png " Response.ContentType = " image/png " Case ElseResponse.ContentType = " image/jpg " End SelectDim fileContents As String = Cache(fileName)Response.BinaryWrite(Convert.FromBase64String(fileContents))End SubEnd Class



Save the changes and close the file.

创建一个Silverlight Project
Silverlight的客户端代码其实都是被编译为assembly 后才被浏览器下载的.这样的话,你可以创建一个独立的Silverlight code的一个project,然后编译为assembly再添加到你的Web site中来. 你还需要复制一份 XAML file来提供对assembly的引用,还有一个client 文件(比如 HTML file)来载入 XAML文件中的特定 Canvas对象.

创建一个Silverlight project
先不管开始打开的ASP.NET Web site project. 打开 Visual Studio, 在 File 菜单上, 点击 Add, 再点 New Project.

在 Visual Studio Installed Templates 面板中, 点击 Silverlight Project.

在Name 框中, 为project起一个名字. 如果是Visual Basic,请输入 ImageUploadVB 而如果是C#则输入 ImageUploadCS , 再点击OK.

现在Visual Studio Solution Explorer 中出现两个project了,一个是WEBSITE,一个是你新创建的Silverlight project. Silverlight project 将包含一个命名为TestPage.html的HTML文件, Page.xaml的 XAML 文件, 还有一个 与XAMLCanvas object相关联的C# 或 Visual Basic编写的并包含 partial class 后台文件.

右键单击 TestPage.html , 点击 Rename. 改名为 Default.html.

双击 Default.html file 进行编辑.更改title 为Image Upload Sample. 保存并退出.

双击 Page.xaml file 进行编辑. 把下面的内容替换到原有内容,请选择你使用的语言.注意,对于不同的语言,XAML文件不同的地方就在于两处,在 XAML Canvas的父结点中的x:Class 属性,还有一个就是编译好的assembly名称.

CS

  
    
< Canvas x:Name = " parentCanvas " xmlns = " http://schemas.microsoft.com/client/2007 " xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml " Loaded = " Page_Loaded " x:Class = " ImageUploadCS.Page;assembly=ClientBin/ImageUploadCS.dll " Width = " 800 " Height = " 600 " Background = " White " > < Canvas x:Name = " ButtonCanvas " Background = " Navy " > < TextBlock x:Name = " UploadButton " FontFamily = " Verdana " Width = " 400 " Height = " 30 " Text = " Click Here to upload an image. " /> </ Canvas > < Canvas x:Name = " StatusCanvas " Background = " Green " > < TextBlock x:Name = " ResponseMessage " FontFamily = " Verdana " Foreground = " Green " Canvas.Top = " 30 " Width = " 400 " Height = " 30 " Text = " Image Uploaded. " /> </ Canvas > < Image x:Name = " UploadedImage " Canvas.Top = " 60 " /> </ Canvas >



VB

  
    
< Canvas x:Name = " parentCanvas " xmlns = " http://schemas.microsoft.com/client/2007 " xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml " Loaded = " Page_Loaded " x:Class = " ImageUploadVB.Page;assembly=ClientBin/ImageUploadVB.dll " Width = " 800 " Height = " 600 " Background = " White " > < Canvas x:Name = " ButtonCanvas " Background = " Navy " > < TextBlock x:Name = " UploadButton " FontFamily = " Verdana " Width = " 400 " Height = " 30 " Text = " Click Here to upload an image. " /> </ Canvas > < Canvas x:Name = " StatusCanvas " Background = " Green " > < TextBlock x:Name = " ResponseMessage " FontFamily = " Verdana " Foreground = " Green " Canvas.Top = " 30 " Width = " 400 " Height = " 30 " Text = " Image Uploaded. " /> </ Canvas > < Image x:Name = " UploadedImage " Canvas.Top = " 60 " /> </ Canvas >



保存并关闭该文件.

双击 Page.xaml.cs 或 Page.xaml.vb文件进行编辑. 选择下面的内容覆盖默认的内容(根据你的语言选择).

CS

  
    
using System; using System.Linq; using System.Xml; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Text; using System.IO; using System.Windows.Browser; using System.Windows.Browser.Net; using System.Net; namespace ImageUploadCS{ public partial class Page : Canvas{ public void Page_Loaded( object o, EventArgs e){ // Required to initialize variables InitializeComponent();StatusCanvas.Visibility = Visibility.Hidden;UploadButton.MouseLeftButtonDown += OnUpload;} private void UploadImage( string fileName, string fileContents){ // Create an HTTP request with the path to the web service // to post the image file to. Uri uploadService = new Uri( " Service.asmx/UploadImage " , UriKind.Relative);BrowserHttpWebRequest _request = new BrowserHttpWebRequest(uploadService);_request.Method = " POST " ;_request.ContentType = " application/x-www-form-urlencoded " ; // Add the file contents to the body of the HTTP request. string formBody = " fileName= " + HttpUtility.UrlEncode(fileName) + " & " + " fileContents= " + HttpUtility.UrlEncode(fileContents);UTF8Encoding encoding = new UTF8Encoding(); byte [] formBytes = encoding.GetBytes(formBody);Stream body = _request.GetRequestStream();body.Write(formBytes, 0 , formBytes.Length); // Send the HTTP request. HttpWebResponse response = (HttpWebResponse)_request.GetResponse();body.Close();} private void OnUpload( object sender, EventArgs e){ // Rehide the status canvas with each request. StatusCanvas.Visibility = Visibility.Hidden; // Prompt the user to select an image file. OpenFileDialog ofd = new OpenFileDialog();ofd.EnableMultipleSelection = false ;ofd.Filter = " Image files (*.jpg;*.png)|*.jpg;*.png " ;ofd.Title = " Select an image to upload " ; if (ofd.ShowDialog() == DialogResult.OK){ // Read the contents of the file. string fileName = ofd.SelectedFile.Name;Stream f = ofd.SelectedFile.OpenRead(); byte [] fileBytes = new byte [f.Length]; int byteCount = f.Read(fileBytes, 0 , ( int )f.Length); string fileContents = Convert.ToBase64String(fileBytes); // Post the file contents to the web service. UploadImage(fileName, fileContents); // Print the status of the upload. ResponseMessage.Foreground = new SolidColorBrush(Color.FromRgb( 0 , 0 , 255 ));StatusCanvas.Visibility = Visibility.Visible; // Display the uploaded image. UploadedImage.Source = new Uri( " GetImage.aspx?fileName= " + fileName, UriKind.Relative);}}}}



VB

  
    
Imports SystemImports System.LinqImports System.XmlImports System.WindowsImports System.Windows.ControlsImports System.Windows.DocumentsImports System.Windows.InkImports System.Windows.InputImports System.Windows.MediaImports System.Windows.Media.AnimationImports System.Windows.ShapesImports System.TextImports System.IOImports System.Windows.BrowserImports System.Windows.Browser.NetImports System.NetPartial Public Class PageInherits CanvasPublic Sub Page_Loaded(ByVal o As Object, ByVal e As EventArgs) ' Required to initialize variables InitializeComponent()StatusCanvas.Visibility = Visibility.HiddenAddHandler UploadButton.MouseLeftButtonDown, AddressOf OnUploadEnd SubPrivate Sub UploadImage(ByVal fileName As String, ByVal fileContents As String) ' Create an HTTP request with the path to the web service ' to post the image file to. Dim uploadService As New Uri( " Service.asmx/UploadImage " , UriKind.Relative)Dim _request As New BrowserHttpWebRequest(uploadService)_request.Method = " POST " _request.ContentType = " application/x-www-form-urlencoded " ' Add the file contents to the body of the HTTP request. Dim formBody As String = " fileName= " & HttpUtility.UrlEncode(fileName) & " & " & _ " fileContents= " & HttpUtility.UrlEncode(fileContents)Dim encoding As New UTF8Encoding()Dim formBytes As Byte() = Encoding.GetBytes(formBody)Dim body As Stream = _request.GetRequestStream()body.Write(formBytes, 0 , formBytes.Length) ' Send the HTTP request. Dim response As HttpWebResponse = CType(_request.GetResponse(), HttpWebResponse)body.Close()End SubPrivate Sub OnUpload(ByVal o As Object, ByVal e As EventArgs) ' Rehide the status canvas with each request. StatusCanvas.Visibility = Visibility.Hidden ' Prompt the user to select an image file. Dim ofd As New OpenFileDialog()ofd.EnableMultipleSelection = Falseofd.Filter = " Image files (*.jpg;*.png)|*.jpg;*.png " ofd.Title = " Select an image to upload " If ofd.ShowDialog() = DialogResult.OK Then ' Read the contents of the file. Dim fileName As String = ofd.SelectedFile.NameDim f As Stream = ofd.SelectedFile.OpenRead()Dim fileBytes(f.Length) As ByteDim byteCount As Integer = f.Read(fileBytes, 0 , CInt(f.Length))Dim fileContents As String = Convert.ToBase64String(fileBytes) ' Post the file contents to the web service. UploadImage(fileName, fileContents) ' Print the status of the upload. ResponseMessage.Foreground = New SolidColorBrush(Color.FromRgb( 0 , 0 , 255 ))StatusCanvas.Visibility = Visibility.Visible ' Display the uploaded image. UploadedImage.Source = _New Uri( " GetImage.aspx?fileName= " & fileName, UriKind.Relative)End IfEnd SubEnd Class



保存并关闭该文件.

右键单击Silverlight project的 projec , 点击Build.默认的, Silverlight project将编译到当前project的 ClientBin 文件夹中. 选择 Silverlight project. 在Project 菜单上, 点击 Show All Files 使ClientBin 文件夹显示出来.

拷贝Silverlight Assembly 和文件到Web Site中
到这个时候, 你的Silverlight project 已经可以简单的拷贝到你的Web site中来运行了. 你需要copy HTML file, XAML file, 和编译好的assembly 到 Web site 中来.

拷贝 Silverlight assembly 和 文件到你的Web site
在 Solution Explorer, Silverlight project上, 右键单击 Page.xaml 文件,再点击 Copy.

在 Solution Explorer, 右键单击 Web site project, 再点击 Paste. ( Page.xaml.cs 或 Page.xaml.vb 文件也将拷贝过来. 你可删除它.)

在 Solution Explorer, 在 Silverlight project, 右键单击 Default.xml file, 再点击 Copy.

在 Solution Explorer, 右键单击 Web site project, 再点击 Paste (一个文件名为 TestPage.html.js 也将拷贝过来).

在 Solution Explorer, 在 Silverlight project, 右键单击 Silverlight.js 文件, 再点击 Copy.

在 Solution Explorer, 右键单击 Web site project,再点击 Paste.

右键单击 Web site project, 点击New Folder. 给新文件夹命名为 ClientBin.

在 Solution Explorer, 点击Silverlight project的 project 文件 . 点击Project 菜单, 点 Show All Files. 现在你将看到 ClientBin 文件夹. 打开这个文件夹, 右键单击 ImageUploadVB.dll 或 ImageUploadCS.dll 文件, 点击Copy.

在 Solution Explorer, 右键单击Web site project下的 ClientBin 文件夹 , 选择Paste.

右键单击 Web site project, 点击 New Folder. 命名文件夹为 images.

在 Web site project, 右键单击 Default.html file, 再点 View in Browser来运行这个示例.

你可能感兴趣的:(upload)