When I try to find a solution for uploading large files in ASP.NET I’ve found a component met my requirement. It’s PowerUpload but this is not a free component. Fortunately, when I read the book ASP.NET 3.5 Unleashed I’ve found another solution in this book. Thank to Stephen Walther  and his solution. This solution apply for ASP.NET 2.0 and 3.5. I’ve also tried with ASP.NET 1.1 and it is ok.

Here’s the source code :

In the web.config you put the key httpRuntime and specify maxRequestLength up to 100 MB, requestLengthDiskThreshold is the buffer size for ASP.NET framework read each chunk of byte from uploaded file. Note that requestLengthDiskThreshold is not available with ASP.NET 1.1

For ASP.NET 2.0 and above :

<httpRuntime maxRequestLength=102400 requestLengthDiskThreshold=100/>

For ASP.NET 1.1 :

 <httpRuntime maxRequestLength=102400 />

 

Create an upload page :

WebForm1.aspx :

<%@ Page language=”c#” Codebehind=”WebForm1.aspx.cs” AutoEventWireup=”false” Inherits=”LargeFileUpload.WebForm1″ %>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN” >
<HTML>
 <HEAD>
  <title>WebForm1</title>
  <meta name=”GENERATOR” Content=”Microsoft Visual Studio .NET 7.1″>
  <meta name=”CODE_LANGUAGE” Content=”C#”>
  <meta name=”vs_defaultClientScript” content=”JavaScript”>
  <meta name=”vs_targetSchema” content=”http://schemas.microsoft.com/intellisense/ie5“>
 </HEAD>
 <body MS_POSITIONING=”GridLayout”>
  <form id=”Form1″ method=”post” runat=”server”>
   <INPUT type=”file” id=”fuAttachment” runat=”server”/>
   <br/>
   <asp:Button id=”btnSave” runat=”server”
    Text=”Save”></asp:Button>
   <br/>
   <asp:Repeater id=”rptListFiles” runat=”server”>
    <HeaderTemplate>
     <table border=”1″>
      <tr>
       <th>ID</th>       
       <th>File Name</th>
       <th>File Size (bytes)</th>
      </tr>
    </HeaderTemplate>
    <ItemTemplate>
     <tr>
      <td>
       <%#DataBinder.Eval(Container.DataItem,”Id”)%>
      </td>
      <td>
       <a href=’FileDownload.aspx?ID=<%#DataBinder.Eval(Container.DataItem,”Id”)%>&FileName=<%#DataBinder.Eval(Container.DataItem,”FileName”)%>’><%#DataBinder.Eval(Container.DataItem,”FileName”)%></a>
      </td>
      <td>
       <%#DataBinder.Eval(Container.DataItem,”FileSize”)%>
      </td>
     </tr>
    </ItemTemplate>
    <AlternatingItemTemplate>
     <tr>
      <td>
       <%#DataBinder.Eval(Container.DataItem,”Id”)%>
      </td>
      <td>
       <a href=’FileDownload.aspx?ID=<%#DataBinder.Eval(Container.DataItem,”Id”)%>&FileName=<%#DataBinder.Eval(Container.DataItem,”FileName”)%>’ target=”_blank”><%#DataBinder.Eval(Container.DataItem,”FileName”)%></a>
      </td>
      <td>
       <%#DataBinder.Eval(Container.DataItem,”FileSize”)%>
      </td>
     </tr>
    </AlternatingItemTemplate>
    <FooterTemplate>
     </table>
    </FooterTemplate>
   </asp:Repeater>
  </form>
 </body>
</HTML>

WebForm1.aspx.cs :

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.IO;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace LargeFileUpload
{
 /// <summary>
 /// Summary description for WebForm1.
 /// </summary>
 public class WebForm1 : System.Web.UI.Page
 {
  protected System.Web.UI.WebControls.Button btnSave;
  protected System.Web.UI.WebControls.Repeater rptListFiles;
  protected System.Web.UI.HtmlControls.HtmlInputFile fuAttachment;
  private string strConString;
 
  private void Page_Load(object sender, System.EventArgs e)
  {
   strConString = ConfigurationSettings.AppSettings["UnleashDBConnString"];

   if(!IsPostBack)
   {    
    LoadFileList();    
   }
  }

  #region Web Form Designer generated code
  override protected void OnInit(EventArgs e)
  {
   //
   // CODEGEN: This call is required by the ASP.NET Web Form Designer.
   //
   InitializeComponent();
   base.OnInit(e);
  }
  
  /// <summary>
  /// Required method for Designer support – do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {   
   this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
   this.Load += new System.EventHandler(this.Page_Load);

  }
  #endregion

  private void btnSave_Click(object sender, System.EventArgs e)
  {
   if (fuAttachment.PostedFile == null)
    return;
      
   SqlConnection con = new SqlConnection(strConString);
               
   using (con)
   {
    con.Open();
    int id = InsertFile(con, GetFileNameFromFullFileName(fuAttachment.PostedFile.FileName));
    if(id > 0)
     StoreFile(con, id, fuAttachment.PostedFile.InputStream);
   }

   LoadFileList();
  }

  private string GetFileNameFromFullFileName(string strFullFileName)
  {
   if(string.Empty.Equals(strFullFileName))
    return string.Empty;
   string strFileName = string.Empty;
   int iPos = strFullFileName.LastIndexOf(“\\”);
   if(iPos > -1)
    return strFullFileName.Substring(iPos + 1);
   return string.Empty;
  }

  private int InsertFile(SqlConnection con, string fileName)
  {
   // parse file name with asp.net 1.1
   
   string strInsertCommand = @”
                                    INSERT INTO Attachment(FileName) VALUES(@fileName)
                                    SELECT @id = SCOPE_IDENTITY()
                                   “;
   SqlCommand cmd = new SqlCommand();
       
   cmd.CommandText = strInsertCommand;
   cmd.Connection = con;

   cmd.Parameters.Add(new SqlParameter());
   cmd.Parameters.Add(new SqlParameter());
   
   cmd.Parameters[0].ParameterName = “@fileName”;
   cmd.Parameters[0].Size = 50;   
   cmd.Parameters[0].Value = fileName;

   cmd.Parameters[1].ParameterName = “@id”;
   cmd.Parameters[1].Size = 4;
   cmd.Parameters[1].Direction = ParameterDirection.Output;

   cmd.ExecuteNonQuery();
   if (cmd.Parameters[1].Value != DBNull.Value)
    return Convert.ToInt32(cmd.Parameters[1].Value);

   return 0;
  }

  private void StoreFile(SqlConnection con,int id, Stream byteStream)
  {
   int iBufferLength = 8040;
   // Step 1 update first byte stream
   string strUpdateCommandStep1 = @”UPDATE Attachment Set FileContent=@fileContent Where ID = @id”;
   SqlCommand cmdStep1 = new SqlCommand();

   cmdStep1.CommandText = strUpdateCommandStep1;
   cmdStep1.Connection = con;
       
   BinaryReader br = new BinaryReader(byteStream);

   byte[] buffer = br.ReadBytes(iBufferLength);

   bool isContinue = true;

   if (buffer != null)
   {
    cmdStep1.Parameters.Add(new SqlParameter());
    cmdStep1.Parameters.Add(new SqlParameter());

    cmdStep1.Parameters[0].ParameterName = “@fileContent”;
    cmdStep1.Parameters[0].Value = buffer;
    cmdStep1.Parameters[0].Size = iBufferLength;

    cmdStep1.Parameters[1].ParameterName = “@id”;
    cmdStep1.Parameters[1].SqlDbType = SqlDbType.Int;
    cmdStep1.Parameters[1].Size = 4;
    cmdStep1.Parameters[1].Value = id;

    cmdStep1.ExecuteNonQuery();
   }
   else
   {
    isContinue = false;
   }

   if (!isContinue)
    return;

   // Step 2 continue read from byte stream and update to database
   string strUpdateCommandStep2 = “UPDATE Attachment Set FileContent.Write(@buffer, null, 0) Where ID = @id “;
   SqlCommand cmdStep2 = new SqlCommand();
       
   cmdStep2.Connection = con;
   cmdStep2.CommandText = strUpdateCommandStep2;
   cmdStep2.Parameters.Add(new SqlParameter());
   cmdStep2.Parameters.Add(new SqlParameter());
       
   cmdStep2.Parameters[0].ParameterName = “@buffer”;
   cmdStep2.Parameters[0].SqlDbType = SqlDbType.VarBinary;
   cmdStep2.Parameters[0].Size = iBufferLength;

   cmdStep2.Parameters[1].ParameterName = “@id”;
   cmdStep2.Parameters[1].SqlDbType = SqlDbType.Int;
   cmdStep2.Parameters[1].Size = 4;
   cmdStep2.Parameters[1].Value = id;       

   buffer = br.ReadBytes(iBufferLength);
   while (buffer.Length > 0)
   {           
    cmdStep2.Parameters[0].Value = buffer;
           
    cmdStep2.ExecuteNonQuery();

    buffer = br.ReadBytes(iBufferLength);
   }

   br.Close();
  }   
  private void LoadFileList()
  {
   SqlConnection con = new SqlConnection(strConString);

   using(con)
   {
    SqlCommand cmd  = con.CreateCommand();
    cmd.CommandText = @”SELECT
          Id, FileName, FileContent, DATALENGTH(FileContent) As FileSize
         From Attachment”;         

    SqlDataAdapter da = new SqlDataAdapter(cmd);
    con.Open();
    DataTable dtb = new DataTable();
    da.Fill(dtb);

    if(dtb != null)
    {
     rptListFiles.DataSource = dtb;
     rptListFiles.DataBind();
    }
   }
  }
 }
}

 

FileDownLoad.aspx :

<%@ Page language=”c#” Codebehind=”FileDownload.aspx.cs” AutoEventWireup=”false” Inherits=”LargeFileUpload.FileDownload” %>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN” >

<html>
  <head>
    <title>FileDownload</title>
    <meta name=”GENERATOR” Content=”Microsoft Visual Studio .NET 7.1″>
    <meta name=”CODE_LANGUAGE” Content=”C#”>
    <meta name=vs_defaultClientScript content=”JavaScript”>
    <meta name=vs_targetSchema content=”http://schemas.microsoft.com/intellisense/ie5“>
  </head>
  <body MS_POSITIONING=”GridLayout”>
 
    <form id=”Form1″ method=”post” runat=”server”>

     </form>
 
  </body>
</html>

FileDownload.aspx.cs :

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.IO;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace LargeFileUpload
{
 /// <summary>
 /// Summary description for FileDownload.
 /// </summary>
 public class FileDownload : System.Web.UI.Page
 {
  private void Page_Load(object sender, System.EventArgs e)
  {
   if(!IsPostBack)
   {
    DownloadFile();
   }
  }

  #region Web Form Designer generated code
  override protected void OnInit(EventArgs e)
  {
   //
   // CODEGEN: This call is required by the ASP.NET Web Form Designer.
   //
   InitializeComponent();
   base.OnInit(e);
  }
  
  /// <summary>
  /// Required method for Designer support – do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {   
   this.Load += new System.EventHandler(this.Page_Load);
  }
  #endregion

  private void DownloadFile()
  {
   System.Web.HttpContext context = System.Web.HttpContext.Current;

   if (string.Empty.Equals((context.Request["ID"])))
    return;
   int id = Convert.ToInt32(context.Request["ID"]);

   if (string.Empty.Equals((context.Request["FileName"])))
    return;
   string strFileName = context.Request["FileName"];

   context.Response.Buffer = false;
   context.Response.AddHeader(“Content-disposition”, string.Format(“attachment; filename={0}”, strFileName));
   context.Response.ContentType = “application/octet-stream”;
       
   string strCommandText = “Select FileContent From Attachment Where Id = @id”;
   string strConnString = System.Configuration.ConfigurationSettings.AppSettings["UnleashDBConnString"];

   SqlConnection con = new SqlConnection(strConnString);
   SqlCommand cmd = new SqlCommand();
   cmd.CommandText = strCommandText;
   cmd.Connection = con;
       
   cmd.Parameters.Add(new SqlParameter());
   cmd.Parameters[0].ParameterName = “@id”;
   cmd.Parameters[0].SqlDbType = SqlDbType.Int;
   cmd.Parameters[0].Size = 4;
   cmd.Parameters[0].Value = id;

   using (con)
   {
    con.Open();
    SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);

    if (reader.Read())
    {                            
     int iBufferLength = 8040;
     byte[] chunk = new byte[iBufferLength];
     long iReturnCount = 0;
     long iStartIndex = 0;
     iReturnCount = reader.GetBytes(0, iStartIndex, chunk, 0, iBufferLength);

     while (iReturnCount == iBufferLength)
     {
      context.Response.BinaryWrite(chunk);
      iStartIndex += iBufferLength;

      iReturnCount = reader.GetBytes(0, iStartIndex, chunk, 0, iBufferLength);
     }
               
     // read remain byte from stream
     byte[] actualChunk = new byte[iReturnCount - 1];
     Array.Copy(chunk,0,actualChunk,0,(int)iReturnCount – 1);     
     context.Response.BinaryWrite(actualChunk);
    }                      
   }
  }
 }
}

 

The database use for this demo has one table Attachment :

Column Name

Data Type

Allow Nulls

Id

Int (identity)

 

FileName

Nvarchar(50)

 

FileContent

VarBinary(MAX)

yes

 

http://port25.technet.com/default.aspx

p25.gif

Windows Media Player Download

  Before to start, you should check the version of Windows Media Player installed on your computer. Version 6.4 is supported, but the latest version is recommended.

Windows Media Player
Download
If you need to install or update Windows Media Player, click on the logo to download the version of Windows Media Player compatible with your operating system.

Embedding Windows Media Player

  To embed an object in HTML document, the object class ID is required. The class ID for Windows Media Player 7, 9, 10 and 11 is clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6.Insert the following code into your HTML document to embed Windows Media Player 7 and later:

<OBJECT id=”VIDEO” width=”320″ height=”240″
style=”position:absolute; left:0;top:0;”
CLASSID=”CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6″
type=”application/x-oleobject”>

<PARAM NAME=”URL” VALUE=”your file or url”>
<PARAM NAME=”SendPlayStateChangeEvents” VALUE=”True”>
<PARAM NAME=”AutoStart” VALUE=”True”>
<PARAM name=”uiMode” value=”none”>
<PARAM name=”PlayCount” value=”9999″>
</OBJECT>

In the URL parameter, you can specify a URL (for streaming) or a local file.

If you are using a Mio generator, you should include the video file in your application. Including video reduce bandwidth usage and bring a better user experience.

Most important parameters supported by Windows Media Player 7 and later:

Parameter Default Description

If you want to embed Windows Media Player 6.4 instead of the latest version, the class ID is clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95.

Controlling Windows Media Player from a JavaScript code

  You can control Windows Media Player from scripting.Start playback:

VIDEO.URL=”filename”;

Stop playback:

VIDEO.controls.stop();

More methods:

VIDEO.controls.Pause();

Properties:

VIDEO.PlayState;
VIDEO.controls.CurrentPosition;
VIDEO.controls.Duration;

For more information:

http://msdn2.microsoft.com/en-us/library/ms983653.aspx

SYMPTOMS

loadTOCNode(1, ’symptoms’);

In a Microsoft ASP.NET version 1.1 application, when you access a strong-named assembly that is stored in the \bin directory of your Web application that is not marked with AllowPartiallyTrustedCallersAttribute (APTCA) and when the trust level of the Web application is not set to Full Trust in the Web.config file, then you may receive the following error message instead of the expected SecurityException error message:

Assembly <assembly>.dll security permission grant set is incompatible between appdomains

You will not receive the same error message in ASP.NET version 1.0, but the same underlying issue about strong-named assemblies also exists in ASP.NET 1.0. CAUSE

loadTOCNode(1, ’cause’);

Strong-named assemblies must be stored in the global assembly cache when they are used with ASP.NET Web applications. By default, strong-named assemblies will not grant access to partially trusted code, because of the visibility of strong-named assemblies in the global assembly cache. You can allow partially trusted code to call your strong-named assembly, but only after you explicitly set the AllowPartiallyTrustedCallersAttribute. If you do not explicitly declare the attribute, the caller requires Full Trust to use the code. Only apply the AllowPartiallyTrustedCallersAttribute to your strong-named assemblies after a careful assessment of the code.

 

RESOLUTION

loadTOCNode(1, ‘resolution’);

Install strong-named assemblies in the global assembly cache for ASP.NET 1.0 and 1.1 Web applications. The following steps describe how to install a strong-named assembly in the global assembly cache, and explain how to use the AllowPartiallyTrustedCallersAttribute:

 

Install a Strong-Named Assembly in the Global Assembly Cache

loadTOCNode(2, ‘resolution’);You can use the global assembly cache to share assemblies across many applications. To install the strong-named assembly in the global assembly cache, follow these steps:

1. To create a strong-name assembly, follow the steps in the “More Information” section of this article.
2. Open Visual Studio .NET Command Prompt, and then type the following command: gacutil -I “C:\[PathToBinDirectoryInVSProject]\sampledll.dllNote: sampledll.dll is the name of the DLL that is signed with strong name.

 

Add the APTCA

loadTOCNode(2, ‘resolution’);Assemblies that are intended to be called by partially trusted code declare their intent by the assembly-level custom attribute AllowPartiallyTrustedCallers. To mark the strong-named assembly with APTCA, follow these steps:

1. To create a strong-name assembly, follow the steps in the “More Information” section of this article.
2. Replace the code in Class1 with the following code:Visual C# .NET Code

using System; using System.Reflection; using System.Runtime.InteropServices; using System.Security;  [assembly: AssemblyKeyFile("..\..\key.snk")] [assembly:AllowPartiallyTrustedCallers]   namespace SNAssemblyTest { 	public class Class1 	{	// Test Class 	} }

Visual Basic .NET Code

Imports System.Reflection Imports System.Runtime.InteropServices Imports System.Security  <Assembly: AssemblyKeyFile("....key.snk")>  <Assembly: AllowPartiallyTrustedCallers>   Public Class Class1    ' Test Class End Class

Note Only apply the AllowPartiallyTrustedCallersAttribute after you have considered the security implications and have taken the necessary precautions. These precautions include a code review against the secure coding guidelines that are described in the “Cause” section of this article. Only apply this attribute to assemblies if the following criteria are met:

1. The assemblies have been designed and been built with explicit attention to security considerations to help protect them against all callers, including potentially malicious callers.
2. Appropriate security testing with partially trusted code is completed before the code is released.

 

STATUS

loadTOCNode(1, ’status’);

This behavior is by design.

 

MORE INFORMATION

loadTOCNode(1, ‘moreinformation’);

Steps to Reproduce the Behavior

loadTOCNode(2, ‘moreinformation’);

Create a StrongName Assembly

loadTOCNode(3, ‘moreinformation’);

1. Start Microsoft Visual Studio .NET 2003.
2. On the File menu, point to New, and then click Project.
3. Select Visual C# project or Visual Basic Projects under Project Types.
4. Select Class Library under Templates.
5. Name the project as SNAssemblyTest.
6. Open the Visual Studio .NET Command Prompt, and then change the directory to the current project directory.
7. To create a strong-named key, type the following command: sn -k key.snk
8. Replace the code in Class1 with the following code:Visual C# .NET Code

using System; using System.Reflection; using System.Runtime.InteropServices;  [assembly: AssemblyKeyFile("..\..\key.snk")]  namespace SNAssemblyTest { 	public class Class1 	{	// Test Class 	} }

Visual Basic .NET Code

Imports System.Reflection Imports System.Runtime.InteropServices  <Assembly: AssemblyKeyFile("....key.snk")>   Public Class Class1    ' Test Class End Class

9. On the Build menu, click Build Solution.

Refer to the Assembly in an ASP.NET Web Application

loadTOCNode(3, ‘moreinformation’);

1. Start Visual Studio .NET, and then create a new ASP.NET Web Application project by using Visual C# .NET or Visual Basic .NET.
2. In Solution Explorer, right-click References, and then click Add Reference.
3. Click Browse, and then select the .dll file of the assembly that you created in the “Create a StrongName Assembly” section of this article (SNAssemblyTest.dll).
4. To open the Web.config file, double-click Web.config in the Solution Explorer.
5. Add the following code trust level code in the <system.web> element of the Web.config file:

<trust level="High"  />

6. To run the project, click Start on the Debug menu. You may receive the error that is mentioned in the “Symptoms” section of this article.

REFERENCES

loadTOCNode(1, ‘references’);

For more information, visit the following Microsoft Web sites:

ASP.NET Code Access Security
http://msdn2.microsoft.com/en-us/library/87×8e4d1.aspx (http://msdn2.microsoft.com/en-us/library/87×8e4d1.aspx)
MSDN Magazine “Security Briefs” (Hashing Passwords, The AllowPartiallyTrustedCallers Attribute)
http://msdn.microsoft.com/msdnmag/issues/03/08/SecurityBriefs/default.aspx (http://msdn.microsoft.com/msdnmag/issues/03/08/SecurityBriefs/default.aspx)
Application Domains and Assemblies
http://msdn2.microsoft.com/en-us/library/43wc4hhs(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/43wc4hhs(vs.71).aspx)
Strong Name Tool (Sn.exe)
http://msdn2.microsoft.com/en-us/library/k5b5tt23(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/k5b5tt23(vs.71).aspx)
Version 1 Security Changes for the Microsoft .NET Framework
http://msdn2.microsoft.com/en-us/library/ms994923.aspx (http://msdn2.microsoft.com/en-us/library/ms994923.aspx)
Global Assembly Cache Tool (Gacutil.exe)
http://msdn2.microsoft.com/en-us/library/ex0ss12c(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/ex0ss12c(vs.71).aspx)

Google:

http://www.google.com.vn/search?hl=vi&q=Assembly+security+permission+grant+set+is+incompatible+between+appdomains.+&meta=