July 2008

Uploading file: the .NET MVC way

In ASP.NET, the traditional way of uploading files is as follows.

<form id=”form1″ runat=”server”>
<asp:FileUpload ID=”FileUpload1″ runat=”server” />
<p>
<asp:Button ID=”Button1″ runat=”server” Text=”Upload”
OnClick=”Button1_Click” /></p>
<p>
<asp:Label ID=”Label1″ runat=”server”></asp:Label></p>
</form>

And you have access to the uploaded file like this.

protected void Button1_Click(object sender, EventArgs e)
{
//FileUpload1.PostedFile
}

In .NET MVC, you can achieve the same with the following code.

<form action=”/controller/action/” accept-charset=”UNKNOWN” enctype=”multipart/form-data” method=”post”>
<label for=”file1″>file1</label>
<input id=”file1″ name=”file1″ size=”20″ type=”file” />
</form>

The controller side
foreach (string fileName in Request.Files)
{
HttpPostedFile file = Request.Files[fileName ];
}

It is important to understand the fundamental difference between the traditional web-form based .NET programming methods and the .NET MVC methods. You can still use the server controls, but you can only use them for read-only data rendering purpose, since ViewState is no longer an option in .NET MVC.

-SK

.NET Framework

Comments (0)

Permalink

Compression using the GZipStream and DeflateStream in .NET

What is GZipStream and DeflateStream?

There are two basic compression methods that are exposed in the .NET I/O Framework i.e. System.IO namespace : GZIP and DEFLATE. They (Compression methods) are exposed via streams and support both compression and decompression (which ofcourse makes sense!).

Compression Streams in .NET
  • System.IO.Compression.GZipStream
  • System.IO.Compression.DeflateStream
Important Facts

The compression streams in .NET support compression of streams with a maximum size of 4GB. You will have to break your file down if it is larger than 4GB. A drawback of the .NET compression methods is that you cannot compress multiple files into a single archive file, like you may be used to with WinZip or other similar tool. Atleast this is not avaialable out of the box.

Which one to use - GZip or Deflate?

Both these methods use the same compression algorithm (RFC 1952). But if you are going to be interfacing with other applications that require a more standard scheme, you may choose GZip. Deflate generally results in a smaller size as there is no header information unlike GZip. So you may choose this method if you dont foresee the need for interfacing with applications that might require GZip or you dont care about the header information.

Compressing a File

To compress a file you do the following:

  • Create an Input Stream from the input file
  • Stream inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
  • Create an output stream using the output file
  • Stream outputStream = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write);
  • Wrap the output stream in a GZipStream or DeflateStream. Use the CompressionMode.Compress
  • Stream compStream = new GZipStream(outputStream, CompressionMode.Compress);
  • Read the input stream (use the Read or ReadByte method)
  • byte[] buffer = new byte[inputStream.Length];
    int bytesRead = inputStream.Read(buffer, 0, buffer.Length);
  • Write the bytes read to the compression stream
  • compStream.Write(buffer, 0, buffer.Length);
  • Finally, close all the three streams
  • finally
    {
    inputStream.Close();
    compStream.Close();
    outputStream.Close();
    }
Decompressing a File
  • Create an Input Stream from the compressed file
  • Stream inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
  • Create an output stream using the output file (i.e. Uncompressed file)
  • Stream outputStream = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write);
  • Wrap the Input stream in a GZipStream or DeflateStream
  • compStream = new GZipStream(inputStream, CompressionMode.Decompress);
  • Read the input stream (use the Read or ReadByte method)
  • Write the bytes read to the output stream
  • try
    {
    	//write to compression stream
    	int inByte = compStream.ReadByte();
    	while (inByte != -1)
    	{
    	outputStream.WriteByte((byte)inByte);
    	inByte = compStream.ReadByte();
    	}
    }
  • Finally, close all the three streams
  • finally
    {
    	compStream.Close();
    	inputStream.Close();
    	outputStream.Close();
    }
Final Remarks

As you can see, the compression and decompression steps are complimentary and fairly straight forward. I have noticed (and this is my personal experience) that sometimes when you read one byte at a time and write to the compressed stream you actually get a larger file as an output. I am going to be researching why this is. When I find out so will you. But my workaround has been to read the whole stream or chunks of bytes at a time.

In my next post I will talk about Isolated Storage

Cheers!

.NET Framework

Comments (0)

Permalink

Working with Isolated Storage in .NET

What is Isolated Storage and Why use It?

Putting it simply, an isolated storage is a “place” where an application can store its state information- things such as user settings, some assembly and application configuration information, and other application/assembly state information. So what is so different about that right?

Well a few things and some of these pertain to or relate to application and computer security. Let me explain, usually when an application tries to persist application state, it has to deal with user access rights, trust levels and so on. One way to resolve this is to give the application whatever rights it needs and potentially open up your computer to malware and spyware. Another way is to save information in the database. Now, the latter might be a viable option but in some cases complicates matters. Remeber when you just wanted to save some user settings to the registry (HKEY_LOCAL_USER) or an INI file. Writing to a registry and file system permissions and access is something that we have all gone through. Isolated storage provides some solutions to these problems.

The bottom line here is how would you like it if your application could persist its state without worrying about trust levels, disk permissions etc. and at the same time do it in a limited security sandbox (i.e. without risking the security of the computer)? This is where you say “What is Isolated Storage for 200 please?” and then your boss goes that is our “Daily Double” we are going to bump up your salary by 10% and make you the director of software development. Ok maybe not so drammatic but hey atleast he/she will be happy that you have a potential winner here!

When to use it?

Some of the caveats to Isolated Storage are related to the intended use of isolated storage. They are useful but I quote Peter Aitken from Dev Source “It is not a panacea”! As I mentioned before there are some good uses of Isolated Storage:

  • When you are trying to store user specific information such as user settings, relatively small size application level/assembly specific data.
  • You want to store state information without giving the application permissive user rights
  • You can live within User Quota restrictions set for isolated storage (Isolated storage is not suited for large data sets).
  • You dont want to or cannot (permissions) write information under your Application Directory (..Program Files\..)
  • You want to store data at different scopes - Application, Assembly, User

So What does .NET Offer?

.Net offers many mechanisms for running with lower privileged user access levels, however we are specifically talking about isolated storage here.

The System.IO namespace provides two main classes to manage Isolated Storage:

  • System.IO.IsolatedStorage.IsolatedStorageFile
  • System.IO.IsolatedStorage.IsolatedStorageFileStream
  • System.IO.IsolatedStorage.IsolatedStorageFilePermission

Although the former is named IsolatedStorageFile, it is really a store where you can create files and directories (Similar to System.IO.Directory and System.IO.File). The latter is a FileStream based class that is used to write files to and read files from the store. Since it is derived from System.IO.FileStream you can use all the FileStream methods that you are already familiar with. To Read and Write to the stream you will use the StreamReader and StreamWriter respectively (as usual) or variations there of (Such as XmlReader XmlWriter for Xml files).

Additional Information

Before diving into the how to create stores and files, I would like to summarize a few key points that you need to bear in mind:

  1. Scope: When considering isolated storage, you need to determine how you want to scope the data to be stored.
    • Application Level Data: Machine/Assembly scope. The store in this case you would store information that is specific to the assembly and local machine.
    • User Level Data: Assembly/User scope. The store in this case would store information that is specific to the assembly and user. Note: If you need to specify the user of the store, you will have to use impersonation, otherwise the store will be created for the current user of the system. If someone else logs in, then another store will be created for that user.
  2. Click-Once Applications
    • Click once applications are deployed via web pages. For click-once applications, an application level store is also supported. Application stores only work for click-once applications.
  3. File Permissions
    • The IsolatedStorageFilePermission class encapsulates the permission that can be granted to code for isolated store access. It has properties that allow you to specify the size of store per user and type of usage.
  4. Class Attributes/Annotations
    • The IsolatedStorageFilePermission class also can be used as an annotation for classes that intend to use isolated storage. The purpose of annotating you class is so as to ensure that any isolated store access from within this class will succeed. It also helps debug permission related issues if access is denied.

Creating a file in Isolated Storage

Step 1. Instantitate/Create an isolated storage store. The following code snippet creates a store at the user scope.

IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();

Step 2. Create a isolated storage file stream.

Vista: C:\Users\<username>\AppData\Local\IsolatedStorage
XP: C:\Documents and Settings\<username>\Local Settings\Application Data\IsolatedStorage

IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("UserSettings.set", FileMode.Create, store);

Step 3. Write something to the file

//Write some user data to the stream
 StreamWriter sw = new StreamWriter(fileStream);
 sw.Write("User Preferences");

Step 4. Close the Stream

//close the stream writer
 sw.Close();

Step 5. Test if the file was written - Reading the file

string[] fileNames = store.GetFileNames("*");if (fileNames.Length == 0)
 throw new FileNotFoundException("The Isolated storage file was not created");
foreach (string s in fileNames)
 {
 Console.WriteLine("Contents of: {0}", s);
//Read the file
 IsolatedStorageFileStream stream = new IsolatedStorageFileStream(s, FileMode.Open, store);
//print the contents
 StreamReader sr = new StreamReader(stream);
 Console.WriteLine(sr.ReadToEnd());
sr.Close();
 }
//close the store
 store.Close();

Hope this helps. Happy coding!

Reddy

.NET Framework

Comments (0)

Permalink

New Tallan Blog!

This is a new Tallan Blog created by the Enterprise .Net Architecture group. We will be posting entries on various .Net technologies as well as upcoming events.

We will be doing presentations at various user groups and code camps and all demonstrations and presentations will available here.

General

Comments (0)

Permalink