Upload Any File Type through a Web Service(转载)

Introduction

This article shall describe an approach that may be used to upload any sort of file through a web service from a Windows Forms application. The approach demonstrated does not rely on the ASP.NET file uploader control and allows the developer the opportunity to upload files programmatically and without user intervention. Such an approach may be useful for doing something like processing out the contents of a local message queue when an internet service is available (if the user base were mobile and had only intermittent connectivity). The article also addresses the use of a file size check as a precursor to allowing a file to upload through the service.

image001.png

Figure 1: Test application shown uploading a file

image002.jpg

Figure 2: Mixed bag of different file types in transient storage folder

Getting Started

The solution contains two projects: one is an ASP.NET Web Service project (Uploader) and the other is a Windows Forms test application (TestUploader) used to demonstrate uploading files through the web method provided in the web service project.

The web service project contains only a single web service (FileUploader) which in turn contains only a single web method (UploadFile). The Windows Forms application contains only a single form which contains the controls (one textbox and two buttons used in conjunction with an OpenFileDialog control) and the code necessary to select and upload files through the web service.

image003.png

Figure 3: Solution Explorer with the both projects visible

Code: Uploader Web Service Project

The Uploader web service project is an ASP.NET web service project containing a single web service called FileUploader. This web service exposes a single web method called UploadFile. The code for this web service begins with the following:

Collapse Copy Code
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.IO;

namespace Uploader
{
    /// <summary>
    /// This web method will provide an web method to load any
    /// file onto the server; the UploadFile web method
    /// will accept the report and store it in the local file system.
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class FileUploader : System.Web.Services.WebService
    {

The class starts out with the default imports. I added System.IO to the defaults to support the use of file and memory streams. The web service namespace is left as the default http://tempuri.org/, which of course will have to be updated if the service were deployed.

The remainder of the code supplied in this class is used to define the web method used to upload the file; the code is annotated. The essential process is that files converted to byte arrays are passed along with the full name of the file (not the path), including the extension as arguments, to the UploadFile web method. The byte array is passed to a memory stream, and a file stream is opened pointing to a newly created file (named the name of the original file) within the target folder used to store the files. Once the file stream has been created, the memory stream is written into the file stream and then the memory stream and file stream are disposed of.

The web method is set up to return a string. If all goes well, the string returned will read, “OK.” If not, the error message encountered will be returned to the caller.

Collapse Copy Code
[WebMethod]
        public string UploadFile(byte[] f, string fileName)
        {
            // the byte array argument contains the content of the file
            // the string argument contains the name and extension
            // of the file passed in the byte array
            try
            {
                // instance a memory stream and pass the
                // byte array to its constructor
                MemoryStream ms = new MemoryStream(f);
 
                // instance a filestream pointing to the
                // storage folder, use the original file name
                // to name the resulting file
                FileStream fs = new FileStream
                    (System.Web.Hosting.HostingEnvironment.MapPath
                    ("~/TransientStorage/") +
                    fileName, FileMode.Create);
 
                // write the memory stream containing the original
                // file as a byte array to the filestream
                ms.WriteTo(fs);
 
                // clean up
                ms.Close();
                fs.Close();
                fs.Dispose();
 
                // return OK if we made it this far
                return "OK";
            }
            catch (Exception ex)
            {
                // return the error message if the operation fails
                return ex.Message.ToString();
            }
        }
    }
}

Code: Test Uploader Windows Forms Application

The test application contains a single Windows Forms class. This form contains a text box used to display the name of the file selected for upload, a browse button to launch an open file dialog box that is used to navigate to and select a file for upload, and an upload button which is used to pass the file to the web service so that the selected file may be stored on the server. The code for this class begins with the following:

Collapse Copy Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
 
namespace TestUploader
{
    /// <summary>
    /// A test form used to upload a file from a windows application using
    /// the Uploader Web Service
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
 
        private void Form1_Load(object sender, EventArgs e)
        {
            // do nothing
        }

Aside from the default imports, I have added only System.IO to the list, this being necessary to support working with files. The namespace and class declarations are in the default configuration. In addition to System.IO, the project also adds in a web reference pointing to the File Uploader web service. The reference is given the alias of Uploader.

The next bit of code in the class is a private method used to prepare the file for submittal to the web service and to actually make that submittal. The code below is annotated to describe the activity, but the essential parts of the operation are to check the file size to see if the web service will accept the file and to convert the file to a byte array. By default, the web server will accept uploads smaller than 4 MB in size; the web.config file must be updated in order to support larger uploads.

When everything is ready, the byte array and the name of the file, including the extension, is passed to an instance of the web service web method. Note that when setting up the demo, you will have remove and add the web reference back into the project in order for it to work for you.

Collapse Copy Code
        /// <summary>
        /// Upload any file to the web service; this function may be
        /// used in any application where it is necessary to upload
        /// a file through a web service
        /// </summary>
        /// <param name="filename">Pass the file path to upload</param>
        private void UploadFile(string filename)
        {
            try
            {
                // get the exact file name from the path
                String strFile = System.IO.Path.GetFileName(filename);
 
                // create an instance fo the web service
                TestUploader.Uploader.FileUploader srv = new
                TestUploader.Uploader.FileUploader();
 
                // get the file information form the selected file
                FileInfo fInfo = new FileInfo(filename);
 
                // get the length of the file to see if it is possible
                // to upload it (with the standard 4 MB limit)
                long numBytes = fInfo.Length;
                double dLen = Convert.ToDouble(fInfo.Length / 1000000);
 
                // Default limit of 4 MB on web server
                // have to change the web.config to if
                // you want to allow larger uploads
                if (dLen < 4)
                {
                    // set up a file stream and binary reader for the
                    // selected file
                    FileStream fStream = new FileStream(filename,
                    FileMode.Open, FileAccess.Read);
                    BinaryReader br = new BinaryReader(fStream);
 
                    // convert the file to a byte array
                    byte[] data = br.ReadBytes((int)numBytes);
                    br.Close();
 
                    // pass the byte array (file) and file name to the web
                    service
                    string sTmp = srv.UploadFile(data, strFile);
                    fStream.Close();
                    fStream.Dispose();
 
                    // this will always say OK unless an error occurs,
                    // if an error occurs, the service returns the error
                    message
                    MessageBox.Show("File Upload Status: " + sTmp, "File
                    Upload");
                }
                else
                {
                    // Display message if the file was too large to upload
                    MessageBox.Show("The file selected exceeds the size limit
                    for uploads.", "File Size");
                }
            }
            catch (Exception ex)
            {
                // display an error message to the user
                MessageBox.Show(ex.Message.ToString(), "Upload Error");
            }
        }

Following the UploadFile method, the next bit of code is used to handle the browse button’s click event. This code is used merely to display an open file dialog to the user and to take the file selected through that dialog and display the file name in the form’s file name text box.

Collapse Copy Code
        /// <summary>
        /// Allow the user to browse for a file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "Open File";
            openFileDialog1.Filter = "All Files|*.*";
            openFileDialog1.FileName = "";
 
            try
            {
                openFileDialog1.InitialDirectory = "C:\\Temp";
            }
            catch
            {
                // skip it
            }
 
            openFileDialog1.ShowDialog();
 
            if (openFileDialog1.FileName == "")
                return;
            else
                txtFileName.Text = openFileDialog1.FileName;

        }

The class wraps up with the button click event handler for the upload button. This handler merely checks for text in the file name text box and, if something is there, it sends the value to the Upload method.

Collapse Copy Code
        /// <summary>
        /// If the user has selected a file, send it to the upload method,
        /// the upload method will convert the file to a byte array and
        /// send it through the web service
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpload_Click(object sender, EventArgs e)
        {
            if (txtFileName.Text != string.Empty)
                UploadFile(txtFileName.Text);
            else
                MessageBox.Show("You must select a file first.", "No File
                Selected");
        }

That wraps up all of the client- and server-side code necessary to upload any sort of file to a server from a Windows Forms application.

Summary

This article was intended to demonstrate an easy approach to uploading any sort of a file to a web server from a Windows Forms application. This example uses the default upload size of 4096 KB. If you need to upload larger files, you will need to alter this value by changing the httpRuntime maxRequestLength property to the desired value. At the same time, you may need to increase the executionTimeout property to a greater value as well in order to support longer upload times. Take care when altering the values, as Microsoft has established the default 4 MB limit to provide some safety against attempts to upload extremely large files that may hamper access to the server.

History

  • 17 January, 2008 -- Original version posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

salysle


Member

Occupation: Software Developer (Senior)
Location: United States United States

 

转载:http://www.codeproject.com/KB/cs/upload_via_webservice.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Contents Acknowledgments xiii About the Authors xv Part I Web Development Is a Blood Sport—Don't Wander onto the Field Without a Helmet 1 Chapter 1 Security Is a Server Issue and Other Myths 3 Reality Check 3 Security Is a Server Issue 5 Hackers Gain Control Through Insecure Applications 5 Programmers Can Harden Their Own Applications 6 Security Through Obscurity 7 Native Session Management Provides Plenty of Security 9 “My Application Isn’t Major Enough to Get Hacked” 9 The “Barbarians at the Gate” Syndrome 10 Wrapping It Up 10 Part II Is That Hole Really Big Enough to Drive a Truck Through? 11 Chapter 2 Error Handling 13 The Guestbook Application 13 Program Summary 13 Primary Code Listing 14 From the Library of Lee Bogdanoff CONTENTS vi Users Do the Darnedest Things . . . 15 I Wonder What Will Happen If I Do This? 15 Expecting the Unexpected 18 Building an Error-Handling Mechanism 19 Test for Unexpected Input 20 Decide What to Do with Erroneous Data 23 Make the System Mind-Numbingly Easy to Use 24 Wrapping It Up 26 Chapter 3 System Calls 27 Navigating the Dangerous Waters of exec(),system(), and Backticks 27 Using System Binaries with the SUID Bit and sudo 28 Using System Resources 29 Usingescapeshellcmd() and escapeshellarg() to Secure System Calls 30 escapeshellcmd() 30 escapeshellarg() 30 Create an API to Handle All System Calls 31 Why Not Just Escape the Arguments and Be Done? 31 Validate User Input 32 Patch the Guestbook Application 32 ThemoveFile()Function 32 Changes to the Application 34 Wrapping It Up 34 Part III What's In a Name? More Than You Expect 35 Chapter 4 Buffer Overflows and Variable Sanitation 37 What Is a Buffer, How Does It Overflow, and Why Should You Care? 37 Buffers, Stacks, Heaps, and Memory Allocation 39 Consequences of a Buffer Overflow 42 Memory Allocation and PHP 42 Pay Attention to the Latest Security Alerts 44 Prevent Buffer Overflows by Sanitizing Variables 46 Premise: Data Is Guilty Until Proven Innocent, Especially If It Comes from Outside the Application 46 Where Does Data Come From? 48 How to Sanitize Data to Prevent Buffer Overflows 48 Patch the Application 49 Verify That We’re Running the Latest Stable Versions 49 Check Variable Sanitation 51 Wrapping It Up 52 Chapter 5 Input Validation 53 New Feature: Allow Users to Sign Their Guestbook Comments 53 From the Library of Lee Bogdanoff CONTENTS vii The Problem: Users Who Give You More Than You Asked For 54 Spammers 55 Injection Attacks 55 Assumptions: You Know What Your Data Looks Like 55 Database Constraints 56 Logical Constraints 56 The Solution: Regular Expressions to Validate Input 57 Tainted Data 57 Regexes 101 58 That Greedy, Lazy . . . Regex! 62 Common Input Validation Patterns 65 Wrapping It Up 67 Chapter 6 Filesystem Access: Accessing the Filesystem for Fun and Profit 69 Opening Files 69 Local Filesystem Access 69 Remote Filesystem Access 71 Preventing Remote Filesystem Exploits 72 Creating and Storing Files 73 Allowing File Uploads 73 Storing Files Safely 75 Changing File Properties Safely 76 Changing File Permissions in UNIX, Linux, and Mac OS X 76 Changing Windows File Permissions 77 Changing File Permissions in PHP 87 Patching the Application to Allow User-Uploaded Image Files 88 Modify the API 88 Create the Upload Form 90 Wrapping It Up 90 Part IV “Aw come on man, you can trust me” 93 Chapter 7 Authentication 95 What Is User Authentication? 95 Usernames and Passwords 97 Image Recognition 99 Privileges 100 How to Authenticate Users 101 Directory-Based Authentication 101 User Database 114 Storing Usernames and Passwords 115 Encryption 115 Password Strength 116 Assess Your Vulnerability 117 From the Library of Lee Bogdanoff CONTENTS viii Patching the Application to Authenticate Users 117 Add User Database Table and Double-Check Database Security 118 Create Authentication API 119 Wrapping It Up 120 Chapter 8 Encryption 121 What Is Encryption? 121 Choosing an Encryption Type 123 Algorithm Strength 123 Speed Versus Security 124 Use of the Data 124 Password Security 125 Patching the Application to Encrypt Passwords 125 Modifying the User Table 126 Create the Encryption and Salting Functions 126 Modify the Password Validation System 127 Wrapping It Up 128 Chapter 9 Session Security 129 What Is a Session Variable? 129 Major Types of Session Attacks 129 Session Fixation 130 Session Hijacking 131 Session Poisoning 133 Patching the Application to Secure the Session 133 Wrapping It Up 136 Chapter 10 Cross-Site Scripting 137 What Is XSS? 137 Reflected XSS 137 Stored XSS 138 Patching the Application to Prevent XSS Attacks 138 Wrapping It Up 139 Part V Locking Up for the Night 141 Chapter 11 Securing Apache and MySQL 143 Programming Languages, Web Servers, and Operating Systems Are Inherently Insecure 143 Securing a UNIX, Linux, or Mac OS X Environment 144 Update the Operating System 145 Securing Apache 147 Upgrade or Install the Latest Stable Version of Apache 147 Give Apache Its Own User and Group 149 From the Library of Lee Bogdanoff CONTENTS ix Hide the Version Number and Other Sensitive Information 151 Restrict Apache to Its Own Directory Structure 152 Disable Any Options You Don’t Explicitly Need 153 Install and Enable ModSecurity 154 Securing MySQL 159 Upgrade or Install the Latest Version 159 Disable Remote Access 163 Change Admin Username and Password 163 Delete Default Database Users and Create New Accounts for Each Application 164 Delete the Sample Databases 165 Wrapping It Up 166 Chapter 12 Securing IIS and SQL Server 167 Securing a Windows Server Environment 167 Update the Operating System 168 Securing IIS 177 Reduce the Server’s Footprint 177 Secure the Web Root 179 Securing SQL Server 187 Install or Upgrade to the Latest Version 187 Secure Microsoft SQL Server 200 Wrapping It Up 205 Chapter 13 Securing PHP on the Server 207 Using the Latest Version of PHP 207 Examining the Zend Framework and Zend Optimizer 208 Finding the Latest Stable Version of PHP 212 Using the Suhosin Patch and Extension 213 Using the Security Features Built into PHP and Apache 213 safe_mode 213 SuEXEC 214 Using ModSecurity 215 Hardening php.ini 216 Wrapping It Up 218 Chapter 14 Introduction to Automated Testing 219 Why Are We Talking About Testing in a Security Book? 219 Testing Framework 220 Types of Tests 222 Unit Tests 222 System Tests 223 Choosing Solid Test Data 223 Wrapping It Up 224 From the Library of Lee Bogdanoff CONTENTS x Chapter 15 Introduction to Exploit Testing 225 What Is Exploit Testing? 225 Fuzzing 226 Installing and Configuring PowerFuzzer 227 Using PowerFuzzer 231 Testing Toolkits 233 Obtaining CAL9000 234 Using CAL9000 235 Proprietary Test Suites 246 Benefits and Features of a Proprietary Test Suite 246 Using a Proprietary Test Suite to Scan Your Application 247 Wrapping It Up 254 Part VI “Don’t Get Hacked” Is Not a Viable Security Policy 255 Chapter 16 Plan A: Designing a Secure Application from the Beginning 257 Before You Sit Down at the Keyboard . . . 257 Concept Summary 257 Workflow and Actors Diagram 260 Data Design 260 Infrastructure Functions 267 Identifying Points of Failure 269 Login and Logout 269 File Upload 270 User Input 270 Filesystem Access 271 Wrapping It Up 271 Chapter 17 Plan B: Plugging the Holes in Your Existing Application 273 Set Up Your Environment 273 Using a Three-Stage Deployment 273 Using Version Control 275 Application Hardening Checklist 276 Check Your Server Security 276 Find the Vulnerabilities in Your Code 276 Fix the Most Obvious Problems 277 Have Your Code Peer-Reviewed 278 Wrapping It Up 278 Epilogue Security Is a Lifestyle Choice: Becoming a Better Programmer 279 Avoid Feature Creep 279 Write Self-Documenting Code 280 Use the Right Tools for the Job 282 Have Your Code Peer-Reviewed 283 Wrapping It Up 284 From the Library of Lee Bogdanoff CONTENTS xi Appendix Additional Resources 285 PEAR 285 Books 286 Web Sites 287 Tools 288 Integrated Development Environments (IDE) and Frameworks 288 Exploit Testing Tools 288 Automated Testing Tools 288 Glossary 289 Index 293

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值