2007.07.25 01:25

이 아티클은 Silverlight에서 파일을 업로드 하는 예제를 설명하고 있다.
아직 자세히 살펴보지는 않았지만. 파일 업로드를 웹 서비스를 이용하는 방식으로 사용한다면
아무래도 범용성에 많은 제약이 있을 것 같다.

원문 http://www.silverlight.net/QuickStarts/Other/Upload.aspx
-----------------------------------------------------------------------------------------

Introduction

This QuickStart sample demonstrates how to upload the contents of an image file using the Microsoft .NET Framework for Silverlight. It includes an example of how to call a Web service with the HTTP POST method using the .NET Framework for Silverlight.

Run View
Language:

Working with this capability in your Silverlight-based application involves the following tasks:

  • Retrieving the contents of an image file from the user by using the OpenFileDialog object.

  • Calling a Web service using the BrowserHttpWebRequest and HttpWebResponse objects.

Prerequisites (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.

Retrieving a File Using the OpenFileDialog Object

For security reasons, you cannot access the file system directly from your browser code. You can store and retrieve files for your application by using isolated storage. (For more information, see How to: Use Isolated Storage with .NET Framework Silverlight.) However, in cases where you need the user to supply a file for your application, you can use the OpenFileDialog object to present the user with a dialog box where they can specify a file from the file system that your application can access. By default, your code has read-only access to the file, but the dialog box provides an option for users to specify write access as well.

To enable a user to supply a file for your application, create an instance of the OpenFileDialog object, set object properties such as the Title and Filter properties as desired, and call the ShowDialog method. If the user selects a file (or files) and clicks OK, the ShowDialog method will return a DialogResult value of OK, and you can access the selected file or files. You access a selected file by using the SelectedFile property of the OpenFileDialog object. (If you have specified the EnableMultipleSelection property of the OpenFileDialog object as true, you can access multiple files by using the SelectedFiles property.) You use the OpenText or OpenRead methods of the SelectedFile property to access a stream of the file contents.

The following code example shows the use of the OpenFileDialog object to retrieve an image file from the user. Because image files are binary files, the OpenRead method is used to access a stream of the file contents. The file contents are then encoded as a Base64 string and uploaded to the Web server with a Web service call.

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 = False
    ofd.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.Name
        Dim f As Stream = ofd.SelectedFile.OpenRead()
        Dim fileBytes(f.Length) As Byte
        Dim 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 If
End Sub

Calling a Web Service to Upload an Image File

You can call a Web service from Silverlight code by using HTTP POST. You can use the BrowserHttpWebRequest object to make an HTTP request from the browser. To include the contents of an image file in an HTTP POST request, you can encode the binary image file contents as Base64 and include them in the body of the HTTP POST request. In this example, the body of the HTTP POST request is URL-encoded (for example, var1=value1&var2=value2&var3=value3). You can include the name of the image file and the file contents as two URL-encoded variables in the form of fileName=<image file name>&fileContents=<encoded file contents>, as shown in the following example.

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.Hidden

    AddHandler UploadButton.MouseLeftButtonDown, AddressOf OnUpload
End Sub

You may need to enable the use of the HTTP POST method to call Web services in your Web application. To enable HTTP POST calls to Web services for your application, add HttpPost to the protocols section of the webServices configuration section in the system.web configuration for your application as shown in the following code example.

  <system.web>
    <webServices>
      <protocols>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
  </system.web>

For more information about how to call a Web service from Silverlight code, see How To: Use a Proxy to Call an ASP.NET Web Service from Silverlight.

Compiling the Code

You can create a copy of the example to run locally by using the following procedures.

Creating an ASP.NET Web Service

This QuickStart sample uses a Web service to receive the uploaded file contents. For security reasons, cross-domain browser calls are not allowed. That is, the .NET Framework for Silverlight code that runs in the browser that calls the Web service must run in a Web page that is served from the same domain as the Web service. As a result, you must first create a Web site to host both the Silverlight client page and the Web service.

The Web service created in this procedure takes the name of a folder that contains image files as input, and returns a list of the image file names. This is required because the Silverlight client code runs in the browser and does not have access to the file system on the Web server.

To create an ASP.NET Web service

  1. In Visual Studio, on the File menu, click New Web Site.

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

  3. 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.

  4. Double-click 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.

  5. In the App_Code folder, double-click 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 System
    Imports System.Web
    Imports System.Web.Services
    Imports System.Web.Services.Protocols
    Imports System.Web.Caching
    Imports System.IO
    
    <WebService(Namespace:="http:'tempuri.org/")> _
    Public Class SampleUploadServiceVB
        Inherits WebService
    
        Public Sub New()
    
        End Sub
    
        <WebMethod()> _
        Public Sub UploadImage(ByVal fileName As String, ByVal fileContents As String)
            Dim imagePath As String = fileName
    
            HttpContext.Current.Cache.Add(fileName, fileContents, _
                Nothing, DateTime.Now.AddSeconds(30), TimeSpan.Zero, _
                CacheItemPriority.High, Nothing)
        End Sub
    
    End Class
    
    
  6. 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.

  7. Right-click the Web site project, and click Add New Item.

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

  9. Double-click 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" %>
    
    
  10. Save the changes and close the file.

  11. Double-click 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 System
    Imports System.Data
    Imports System.Configuration
    Imports System.Collections
    Imports System.Web
    Imports System.Web.Security
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.WebControls.WebParts
    Imports System.Web.UI.HtmlControls
    Imports System.IO
    Imports System.Text
    
    Partial Public Class GetImage
        Inherits System.Web.UI.Page
    
        Protected 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 extension
                Case "jpg"
                    Response.ContentType = "image/jpeg"
                Case "png"
                    Response.ContentType = "image/png"
                Case Else
                    Response.ContentType = "image/jpg"
            End Select
    
            Dim fileContents As String = Cache(fileName)
    
            Response.BinaryWrite(Convert.FromBase64String(fileContents))
        End Sub
    End Class
    
    
  12. Save the changes and close the file.

Creating a Silverlight Project

Silverlight client code is compiled into an assembly that is downloaded to the browser. As a result, you can create a separate project for your Silverlight code, build that project into an assembly, and copy that assembly to your Web site. You will also copy a XAML file that references the assembly, and a client file (in this case, an HTML file) to load the XAML Canvas object specified in your XAML file.

To create a Silverlight project

  1. Leave your ASP.NET Web site project open. In Visual Studio, on the File menu, click Add, then click New Project.

  2. In the Visual Studio Installed Templates panel, click Silverlight Project.

  3. In the Name box, type a name for the project. Type ImageUploadVB for Visual Basic or ImageUploadCS for C#, and then click OK.

    The Visual Studio Solution Explorer will show both the Web site created previously, and your new Silverlight project. The Silverlight project will contain an HTML file named TestPage.html, a XAML file named Page.xaml, and a C# or Visual Basic file that contains a partial class that is associated with the XAML Canvas object specified in the Page.xaml file.

  4. Right-click the TestPage.html file, and click Rename. Change the file name to Default.html.

  5. Double-click the Default.html file to edit its contents. Change the title tag to Image Upload Sample. Save the changes and close the file.

  6. Double-click the Page.xaml file to edit its contents. Replace the default contents with the following XAML code for your chosen programming language. Note that the only difference between the XAML files for the different languages is the name of the class and compiled assembly identified in the x:Class attribute of the parent XAML Canvas.

    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>
    
    
  7. Save the changes and close the file.

  8. Double-click the Page.xaml.cs or Page.xaml.vb file to edit its contents. Replace the default contents with the following code for your chosen programming language.

    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 System
    Imports System.Linq
    Imports System.Xml
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Documents
    Imports System.Windows.Ink
    Imports System.Windows.Input
    Imports System.Windows.Media
    Imports System.Windows.Media.Animation
    Imports System.Windows.Shapes
    Imports System.Text
    Imports System.IO
    Imports System.Windows.Browser
    Imports System.Windows.Browser.Net
    Imports System.Net
    
    
    Partial Public Class Page
        Inherits Canvas
    
        Public Sub Page_Loaded(ByVal o As Object, ByVal e As EventArgs)
    
            ' Required to initialize variables
            InitializeComponent()
    
            StatusCanvas.Visibility = Visibility.Hidden
    
            AddHandler UploadButton.MouseLeftButtonDown, AddressOf OnUpload
        End Sub
    
        Private 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 Sub
    
        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 = False
            ofd.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.Name
                Dim f As Stream = ofd.SelectedFile.OpenRead()
                Dim fileBytes(f.Length) As Byte
                Dim 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 If
        End Sub
    End Class
    
    
  9. Save the changes and close the file.

  10. Right-click the project file for your Silverlight project, and click Build. By default, a Silverlight project is configured to place the compiled assembly in the ClientBin folder of the Silverlight project. Select the Silverlight project. On the Project menu, click Show All Files to make the ClientBin folder visible.

Copying the Silverlight Assembly and Files to the Web Site

At this point, your Silverlight project is ready to run and simply needs to be copied to your Web site. You need to copy the client HTML file, the XAML file, and the compiled assembly to your Web site to run your Silverlight example.

To copy the Silverlight assembly and files to the Web site

  1. In the Solution Explorer, in your Silverlight project, right-click the Page.xaml file, and then click Copy.

  2. In the Solution Explorer, right-click the Web site project, and then click Paste. (The Page.xaml.cs or Page.xaml.vb file will also be copied. You can delete this copy.)

  3. In the Solution Explorer, in your Silverlight project, right-click the Default.html file, and then click Copy.

  4. In the Solution Explorer, right-click the Web site project, and then click Paste (a file named TestPage.html.js will also be copied).

  5. In the Solution Explorer, in your Silverlight project, right-click the Silverlight.js file, and then click Copy.

  6. In the Solution Explorer, right-click the Web site project, and then click Paste.

  7. Right-click the Web site project, and click New Folder. Name the new folder ClientBin.

  8. In the Solution Explorer, click the project file for your Silverlight project. Click the Project menu, and then click Show All Files. Among the now viewable files and folders you will see a ClientBin folder. Expand this folder, right-click the ImageUploadVB.dll or ImageUploadCS.dll file, and then click Copy.

  9. In the Solution Explorer, right-click the ClientBin folder in the Web site project, and then click Paste.

  10. Right-click the Web site project, and click New Folder. Name the new folder images.

  11. In the Web site project, right-click the Default.html file, and then click View in Browser to run the sample.

신고