Using Plupload in ASP.NET

7. July 2011 18:21

Test Solution Download

PLUploadTest.rar (121.28 kb)

I like plupload, however, using it for a real world application was a bit tough my first time around.  I basically wanted to have the user upload a file, then record that record in the database.

So I made a skeleton version of the code that you can use to help get you started. This will allow you to use Plupload in your asp.net application to do the following:

  • have the user select a file (or files) via plupload
  • Have the user submit a file(s)
  • Have a generic handler be aware of the id's of a given object(s) (i.e., a user id)
  • Store the file uploaded into a given directory
  • The ability to store the id's of an object(s), file id and file name from plupload

To accomplish this you will need the following:

  • Plupload
  • Custom javascript (not too much) you will see a file named xdev.plupload.js in js/plupload
  • Enable Page Methods via the ASP.NET ScripManager

 

Once you have a skeleton version of the code you like, I think you'll find it easy to modify and incorporate plupload into your project as well. I love this multifile upload, so why not use it effectively in your website application :)

I will bascially do a copy and paste of the ASP.NET code so you can see what's going on.  I think the best thing about this is the ability to take the files and the ID of your object (i.e., user id) that is uploading them and storing the data in a database.

PLUploadTest.aspx

In the "head" part of the aspx page you will need to reference the following javascript and css

    <script type="text/javascript" src="https://www.google.com/jsapi">
    <script type="text/javascript">
        google.load("jquery", "1.3");
    </script>
    <script src="js/plupload/plupload.full.min.js" type="text/javascript">
    <script src="js/plupload/jquery.plupload.queue.min.js" type="text/javascript">
    <script src="js/plupload/xdev.plupload.js" type="text/javascript">
    <link href="plupload.queue.css" rel="stylesheet" type="text/css" />

In the body section of the ASPX page you will need the following:

    <form id="form1" enctype="application/x-www-form-urlencoded" method="get">

        <div id="uploader" style="width: 525px;">
            <p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.

</div> <br /> <div style="width: 150px; margin-right: 490px;"> <a onclick="SubmitItem(this)" href="#">Submit Item </div> </form>

PLUploadTest.aspx.cs

[WebMethod]
public static string GetIDs()
{
    //This is strictly here just so you can see how you can grab ID's and make plupload aware of them
    //This is useful for data driven application. Example, you need the ID of the user who is uploading a file
    //so you can pull that data out later when the user logs in.

    //default is pipe delimited for js file in function OnGetIDSucceeded
    //IDOfObject1|IDOfObject2
    string IDs = "0|0";

    //These IDs could be pulled from anywhere (i.e, Session, DB, XML file)

    IDs = string.Format("{0}|{1}", "10", "11"); //"10" and "11" and filler so you can have data to mess around with

    return IDs;
}


[WebMethod]
public static void InsertFileRecord(string idOfObject1, string idOfObject2, string fileID, string fileName)
{
    _InsertAttachment(idOfObject1, idOfObject2, fileID, fileName);
}



private static void _InsertAttachment(string idOfObject1, string idOfObject2, string fileID, string fileName)
{
    //TODO: Insert into Database as needed, or whatever data store you are using.
    string doSomething = ""; //left here for debugging purposes...delete as needed
}

UploadHandler.ashx.cs

 

public void ProcessRequest(HttpContext context)
{
    //TODO: Whatever you would like to do now that you have the ID's of the objects
    //Example, could be creating directories for that ID specifically, etc....        
    string _idOfObject1 = context.Request.Headers["IDofObject1"].ToString();
    string _idOfObject2 = context.Request.Headers["IDofObject2"].ToString();

    int chunk = context.Request["chunk"] != null ? int.Parse(context.Request["chunk"]) : 0;
    string fileName = context.Request["name"] != null ? context.Request["name"] : string.Empty;

    //TODO: change as needed for your application
    string uploadPath = context.Server.MapPath("~/documents/"); 

    HttpPostedFile fileUpload = context.Request.Files[0];

    fileName = fileName.Insert(0, string.Format("{0:MM}{0:dd}{0:yyyy}", DateTime.Now));

    using (var fs = new FileStream(Path.Combine(uploadPath, fileName), chunk == 0 ? FileMode.Create : FileMode.Append))
    {
        var buffer = new byte[fileUpload.InputStream.Length];
        fileUpload.InputStream.Read(buffer, 0, buffer.Length);

        fs.Write(buffer, 0, buffer.Length);
    }

}

public bool IsReusable
{
    get { return false; }
}

 

 

One of the custom javascript methods that handles the files and data. Please download the zip file to see the entire solution.

 

function SubmitItem(e) {

    //get a copy of the current uploader
    var uploader = $('#uploader').pluploadQueue();
    var obj = uploader.settings;

    //alert("Local js variable ID1: " + IDofObject);
    //alert("Local js variable ID2: " + IDOfObject2);

    //alert("Header Object1: " + obj.headers.IDofObject1);
    //alert("Header Object2: " + obj.headers.IDofObject2);

    // Validate number of uploaded files
    if (uploader.total.uploaded == 0) {
        // Files in queue upload them first
        if (uploader.files.length > 0) {
            // When all files are uploaded submit form
            uploader.bind('UploadProgress', function () {
                if (uploader.total.uploaded == uploader.files.length)
                    $('form1').submit();
            });

            //now go insert the files into the DB
            uploader.bind('UploadComplete', function (up, f) {

                var obj = up.settings;

                //alert("Upload Complete");

                for (i = 0; i < f.length; i++) {

                    //alert("Name: " + f[i].name);
                    //alert("ID: " + f[i].id);

                    InsertFileRecord(obj.headers.IDofObject1, obj.headers.IDofObject2, f[i].id, f[i].name);
                }

                alert("File(s) Uploaded"); //You may not want this. I just left it here so you can see how it interacts with everything else.

            });

            uploader.start();
        }
        else {

            alert("No files to upload"); //take out or do whatever you would like here because there were zero files
        }
    }

}

 

Resources

http://www.plupload.com/
http://www.plupload.com/example_queuewidget.php
http://www.plupload.com/example_custom.php
http://www.plupload.com/example_events.php
http://www.plupload.com/plupload/docs/api/index.html

 

 

PLUploadTest.rar (121.28 kb)

Tags:

ASP.NET | Javascript

Install ASP.NET Membership Provider on a Shared Hosting Company

20. September 2010 20:23

I usually use Go Daddy as my hosting company. I love Go Daddy strictly for the cost and Admin Tools they offer to manage all aspects of your account. Well I'm working on a project right now where the hosting company that this site uses is not as elaborate as Go Daddy.  Long story short, I submitted a support ticket to have them install the ASP.NET Membership Provider on the database for the website account. Well I got a response back saying it had to be submitted to a "higher tier" support. Fine, understandable.

Anyway, me being the impatient person I am sometimes wanted to do this myself without having to use the aspnet_regsql tool...since I didn't have permission anyway on the hosting company database. Luckily it's quite simple to install the ASP.NET Membership Provider on a shared hosting environment by yourself without having to ask the hosting company to do it for you.

You can accomplish this by still using the aspnet_regsql tool provided with the .NET framework. However, there is an option -sqlexportonly that allows you to output the scripts it generates so you can run them directly on the hosting database you do have access to.

So here is how to do it.

Open a command prompt and run the aspnet_regsql tool as follows but replacing TestDB with your database name

Command to Create the Add Scripts:

aspnet_regsql -d TestDB -A all -sqlexportonly C:\ASPNET_SQLMembershipProviderTestDB.sql

Command to Create the Remove Scripts:

aspnet_regsql -d TestDB -R all -sqlexportonly C:\ASPNET_SQLMembershipProviderTestDBRemove.sql


Here is a screenshot:

 

Now you can run the scripts (Add or Remove) as needed for the database you are trying to install this on. Since I chose the option -A all it will install everything the provider providers (i.e., personalization, roles, membership, etc...)


References:

This will provide options you can provide for the aspnet_regsql command

ASPNET_REGSQL: http://msdn.microsoft.com/en-us/library/x28wfk74.aspx

 

 

Tags:

ASP.NET

ASP.NET C# Form Generator

27. July 2010 19:14

I decided to make a simple tool generate forms for ASP.NET.  The link to the tool is below.  If you'd like more of a background on the form keep reading. Otherwise, hope the tool helps you!

ASP.NET C# Form Generator

-----------------------------------------------------

Usually every website needs some type of input form. Whether that is for a contact page, suggested comments page, etc...  Because I find this to be a tedious task I decided to make a simple ASP.NET C# Form Generator.  Am I that lazy? Probably :)  I guess don't like wasting time when I don't need to.  To create a form I would always simply copy and paste a previous form and them modify as needed. As simple as that sounds, the modifying part is/was annoying. I would have to change the text and variable names as needed for the new form.

Now, with my simple form generator I don't have to worry about that anymore. I simply type in the name of the field I want and select what type of field it is.  I am not claiming this to be a tool that is used for advanced forms. Just simple and easy. 

ASP.NET C# Form Generator

As you enter in your field information, it will append the markup and code behind per field. Now I really only have to copy and paste and that's it. No modification needed.  It will also create a simple email message that you can use for whatever code you already have to send emails via your forms.

This tool is geared towards developers, as in the end it can be used for a simple form. If anything it can be used as a template to get started.  Either way I think you will find this saves you time.  Below is a screenshot of the tool.


If this doesn't serve your purpose...sorry :)  I needed something for myself right now to save me some time. However, feel free to drop comments or suggestions as what could be added.

Personally, I don't think I will ever make this tool advanced enough to where I would never have to write code for a form. Partially, because I don't mind writing code to insert to the database or writing code to send emails, because most likely, although similiar, each one will be different. However, this is a good start on implementing a form and getting rid of the tedious tasks.

Tags:

ASP.NET

Using ColorBox in ASP.NET

22. July 2010 22:33

I learned about this jquery lightbox called ColorBox via SitePoint's "jquery Novice to Ninja" e-book. I created just a small sample on how you can go about integrating it into an asp.net application.

Note: thanks SitePoint for the free e-book because of the world cup.

Anyway, this sample simply uses a DataList to create the elements needed for ColorBox to function properly.  This example provides a thumbnail preview of images before the user clicks on one to start navigating through them via ColorBox.

Note: this code is for demo only and other things could be done to clean it up and style the datalist better.

The concept is that you are filling an object such as a DataSet with the fields you need to make this happen. I will post the manual code I used to test this out in the code behind

First, here is a screenshot of the my Visual Studio solution.  I chose to contain all of the ColorBox files in a folder named ColorBox....go figure right?

 

Because I did this I had to edit the CSS file to point to the correct path for all images. In my case one of the lines looked like this:

#cboxOverlay{background:url(/ColorBox/images/overlay.png) 0 0 repeat;}

Notice the path in the url(). You will need to change all lines in the CSS file to their respective image paths as needed.

 

 

Second, here is the result from the code in the browser.


 

Next, here is the markup from the ASPX page.

Finally, here is the code behind to manually create the test data

DataSet ds = new DataSet();

protected void Page_Load(object sender, EventArgs e)
{
    BuildDataSet();
    BuildPhotoList();
}

private void BuildDataSet()
{
    ds.Tables.Add("Photos");
    ds.Tables[0].Columns.Add("ImageUrl");
    ds.Tables[0].Columns.Add("Description");

    DataRow dr1 = ds.Tables[0].NewRow();
    dr1["ImageUrl"] = "~/Images/homer.jpg";
    dr1["Description"] = "Your Description Here";            

    DataRow dr2 = ds.Tables[0].NewRow();
    dr2["ImageUrl"] = "~/Images/marylou.jpg";
    dr2["Description"] = "Your Description Here";

    DataRow dr3 = ds.Tables[0].NewRow();
    dr3["ImageUrl"] = "~/Images/ohoopee1.jpg";
    dr3["Description"] = "Your Description Here";

    DataRow dr4 = ds.Tables[0].NewRow();
    dr4["ImageUrl"] = "~/Images/ohoopee2.jpg";
    dr4["Description"] = "Your Description Here";

    DataRow dr5 = ds.Tables[0].NewRow();
    dr5["ImageUrl"] = "~/Images/ohoopee3.jpg";
    dr5["Description"] = "Your Description Here";

    DataRow dr6 = ds.Tables[0].NewRow();
    dr6["ImageUrl"] = "~/Images/homer.jpg";
    dr6["Description"] = "Your Description Here";

    DataRow dr7 = ds.Tables[0].NewRow();
    dr7["ImageUrl"] = "~/Images/marylou.jpg";
    dr7["Description"] = "Your Description Here";

    DataRow dr8 = ds.Tables[0].NewRow();
    dr8["ImageUrl"] = "~/Images/ohoopee1.jpg";
    dr8["Description"] = "Your Description Here";

    DataRow dr9 = ds.Tables[0].NewRow();
    dr9["ImageUrl"] = "~/Images/ohoopee2.jpg";
    dr9["Description"] = "Your Description Here";

    ds.Tables[0].Rows.Add(dr1);
    ds.Tables[0].Rows.Add(dr2);
    ds.Tables[0].Rows.Add(dr3);
    ds.Tables[0].Rows.Add(dr4);
    ds.Tables[0].Rows.Add(dr5);
    ds.Tables[0].Rows.Add(dr6);
    ds.Tables[0].Rows.Add(dr7);
    ds.Tables[0].Rows.Add(dr8);
    ds.Tables[0].Rows.Add(dr9);
}

private void BuildPhotoList()
{
    dlColorBox.DataSource = ds;
    dlColorBox.DataBind();
}

 

And that's about it. This should get you started with using ColorBox in an asp.net application without having to statically have all of the elements on the page at design time.

Happy Coding!

Tags:

ASP.NET

Default Route in ASP.NET 4 URL Routing

21. July 2010 17:50


I was playing around trying to learn URL Routing in ASP.NET 4. I wanted to find a way to have a wildcard or default route to handle any page ending in .ASPX.

I originally came across this post on stackoverflow

http://stackoverflow.com/questions/2704338/asp-net-4-0-web-forms-routing-default-wildcard-route

However, it didn't seem to work (or at least I couldn't get it to work properly).

So I took the concept of that post and created a default route handler that seems to be working OK.

Note: I'm just now learning this, so if you have a better reference for those reading this please leave a link in the comments or leave a suggestion for a better way :)

Here was the goal I was trying to accomplish

http://localhost:18849/Default -> http://localhost/Default.aspx
http://localhost:18849/About -> http://localhost/About.aspx
http://localhost:18849/Contact -> http://localhost/Contact.aspx
http://localhost:18849/Dir1/Page1 -> http://localhost/Dir1/Page1.aspx

Here is a screenshot of my test solution in Visual Studio 2010

 

 

Now for what I did.

First thing I did was add a reference to System.Web.Routing

Next, you need to add code to the global.asax file to register your routes. My resulting Global.asax.cs page looked like this

void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            RegisterRoutes(RouteTable.Routes);

        }

        void RegisterRoutes(RouteCollection routes)
        {
            routes.Ignore("{resource}.axd/{*pathInfo}");
                     
            //TODO: Rest of known routes here

            //Default route
            routes.Add(new Route("{*value}", new DefaultRouteHandler()));

        }



You'll notice a class called DefaultRouteHandler().  This is class I created to handle the route.

So you'll want to add a new class to your solution called DefaultRouteHandler.cs.  This class will implement the Interface IHttpHandler

public class DefaultRouteHandler: IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            var pageUrl = requestContext.HttpContext.Request.Path + ".aspx";
            pageUrl = string.Format("~{0}", pageUrl);

            var page = new object();

            try
            {
                page = BuildManager.CreateInstanceFromVirtualPath(pageUrl, typeof(Page));

                if (page != null)
                {
                    //Set the forms postback url to the route
                    var webForm = page as Page;
                    if (webForm != null)
                        webForm.Load += delegate
                        {
                            webForm.Form.Action =
                            requestContext.HttpContext.Request.RawUrl;
                        };
                }

                return page as IHttpHandler;
            }
            catch (Exception ex)
            {
                page = BuildManager.CreateInstanceFromVirtualPath("~/NotFound.aspx", typeof(Page));

                return page as IHttpHandler;
            }
            
        }
    }



You'll see in the code above I grab the Path of the request and append .aspx to it. This is because if someone types in http://localhost:18849/Contact we

need to add the .aspx to it so we can use it in the CreateInstanceFromVirtualPath method.

I wrapped this in a try-catch method because if the CreateInstanceFromVirtualPath failed, then we can redirect to our basic NotFound.aspx page.


With this code I have accomplished what I set out to do by having a route for my .aspx pages that don't do anything special.


Other References:

ASP.NET.4GuysFromRolla.com: URL Routing in ASP.NET 4.0

http://www.4guysfromrolla.com/articles/012710-1.aspx


Walkthrough: Using ASP.NET Routing in a Web Forms Application

http://msdn.microsoft.com/en-us/library/dd329551.aspx

How to: Define Routes for Web Forms Applications

http://msdn.microsoft.com/en-us/library/cc668177.aspx

Tags:

ASP.NET




My Random Thought

I think the OCW is a great thing to have available to those who are in school, just finished school or just want to educate themself

http://ocwconsortium.org/

John On Twitter

Discounts