usando Plupload con ASP.NET/C#
jquery-plugins httphandler (2)
Aquí hay un ejemplo completo de trabajo que escribí para ti:
<%@ Page Title="Home Page" Language="C#" %>
<%@ Import Namespace="System.IO" %>
<script runat="server" type="text/c#">
protected void Page_Load(object sender, EventArgs e)
{
// Check to see whether there are uploaded files to process them
if (Request.Files.Count > 0)
{
int chunk = Request["chunk"] != null ? int.Parse(Request["chunk"]) : 0;
string fileName = Request["name"] != null ? Request["name"] : string.Empty;
HttpPostedFile fileUpload = Request.Files[0];
var uploadPath = Server.MapPath("~/TicketUploads");
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);
}
}
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head id="Head1" runat="server">
<title></title>
<style type="text/css">@import url(css/plupload.queue.css);</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.3");
</script>
<script type="text/javascript" src="/plupload/js/gears_init.js"></script>
<script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>
<script type="text/javascript" src="/plupload/js/plupload.full.min.js"></script>
<script type="text/javascript" src="/plupload/js/jquery.plupload.queue.min.js"></script>
<script type="text/javascript">
$(function() {
$("#uploader").pluploadQueue({
// General settings
runtimes : ''gears,flash,silverlight,browserplus,html5'',
url : ''/default.aspx'',
max_file_size : ''10mb'',
chunk_size : ''1mb'',
unique_names : true,
// Resize images on clientside if we can
resize : {width : 320, height : 240, quality : 90},
// Specify what files to browse for
filters : [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
],
// Flash settings
flash_swf_url : ''/plupload/js/plupload.flash.swf'',
// Silverlight settings
silverlight_xap_url : ''/plupload/js/plupload.silverlight.xap''
});
// Client side form validation
$(''form'').submit(function(e) {
var uploader = $(''#uploader'').pluploadQueue();
// 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)
$(''form'').submit();
});
uploader.start();
} else
alert(''You must at least upload one file.'');
e.preventDefault();
}
});
});
</script>
</head>
<body>
<form id="Form1" runat="server">
<div id="uploader">
<p>You browser doesn''t have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
</div>
</form>
</body>
</html>
Como verá en este ejemplo, los archivos se cargan en la misma página llamada default.aspx
. Observe que los parámetros como el chunk
y el name
están POSTados, por lo que no debe usar Request.QueryString
para leerlos, sino que debe Request["chunk"]
directamente, ya que esto también revisará el cuerpo del POST. También debe asegurarse de que la carpeta TicketUploads
exista en el servidor en la raíz.
En este ejemplo, se utiliza la misma página default.aspx para mostrar el formulario de carga y manejar las cargas. En una aplicación del mundo real, esto no es algo que haría. Le recomendaría que use una secuencia de comandos separada que se encargará de las cargas de archivos, como un controlador http genérico (upload.ashx).
Finalmente, notará que he utilizado algunas configuraciones predeterminadas que podría desear modificar y reconfigurar el complemento para que se ajuste a sus necesidades. Acabo de tomar las configuraciones de la documentación.
ACTUALIZAR:
Y como recomendé el uso de un manejador de http genérico separado para manejar las cargas de archivos, aquí se muestra cómo podría verse:
using System.IO;
using System.Web;
public class Upload : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
int chunk = context.Request["chunk"] != null ? int.Parse(context.Request["chunk"]) : 0;
string fileName = context.Request["name"] != null ? context.Request["name"] : string.Empty;
HttpPostedFile fileUpload = context.Request.Files[0];
var uploadPath = context.Server.MapPath("~/TicketUploads");
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);
}
context.Response.ContentType = "text/plain";
context.Response.Write("Success");
}
public bool IsReusable
{
get { return false; }
}
}
Ahora todo lo que queda es reconfigurar el complemento para que apunte a este controlador genérico:
...
runtimes: ''gears,flash,silverlight,browserplus,html5'',
url: ''/upload.ashx'',
max_file_size: ''10mb'',
...
ACTUALIZAR
Pude hacer que todo funcionara correctamente y solo quería publicar con el código actualizado. Usé la sugerencia de Darin Dimitrov sobre el uso de un manejador de http genérico separado para manejar las cargas de archivos y este es el código que se me ocurrió para eso ... avíseme si tiene alguna pregunta.
<%@ WebHandler Language="C#" Class="Upload" %>
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Net;
using System.Web;
public class Upload : IHttpHandler {
public void ProcessRequest(HttpContext context) {
/**
* If ''newTicket'' is "false", then the directory to upload to already exists and we can extract it from
* the ''ticketID'' POST parameter.
*
* If ''newTicket'' is "true", then this is a new Ticket submission so we need to work with a NEW directory
* on the server, so the ID needs to be 1 more than the total number of directories in ~/TicketUploads/
*/
String newTicket = context.Request["newTicket"] != null ? context.Request["newTicket"] : String.Empty;
int theID = -1;
if (newTicket.Equals("true")) {
// we need to calculate a new ID
theID = getNewID(context); // calculate the new ID = # of rows
theID++; // add 1 to make it unique
} else if (newTicket.Equals("false")) {
// we can just get the ID from the POST parameter
theID = context.Request["ticketID"] != null ? Convert.ToInt32(context.Request["ticketID"]) : -1;
} else {
// something went wrong with the ''newTicket'' POST parameter
context.Response.ContentType = "text/plain";
context.Response.Write("Error with ''newTicket'' POST parameter.");
}
// if theID is negative, something went wrong... can''t continue
if (theID < 0) {
return;
}
// ready to read the files being uploaded and upload them to the correct directory
int chunk = context.Request["chunk"] != null ? int.Parse(context.Request["chunk"]) : 0;
string fileName = context.Request["name"] != null ? context.Request["name"] : string.Empty;
var uploadPath = context.Server.MapPath("~/TicketUploads/" + theID + "/");
HttpPostedFile fileUpload = context.Request.Files[0];
// if the NEW directory doesn''t exist, create it
DirectoryInfo di = new DirectoryInfo("" + uploadPath + "");
if (!(di.Exists)) {
di.Create();
}
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);
}
context.Response.ContentType = "text/plain";
context.Response.Write("File uploaded.");
return;
}
}
Estoy intentando integrar el cargador de archivos Plupload en ASP.NET usando C #. He leído el artículo de Angry Monkeys y el blog de Marco Valsecchi, pero estoy un poco perdido.
El C # que sugieren los artículos anteriores es más o menos similar al siguiente:
int chunk = Request.QueryString["chunk"] != null ? int.Parse(Request.QueryString["chunk"]) : 0;
string fileName = Request.QueryString["name"] != null ? Request.QueryString["name"] : string.Empty;
HttpPostedFile fileUpload = Request.Files[0];
using (FileStream fs = new FileStream(Server.MapPath("~/TicketUploads/" + fileName), chunk == 0 ? FileMode.Create : FileMode.Append))
{
Byte[] buffer = new Byte[fileUpload.InputStream.Length];
fileUpload.InputStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
Primero, configuré la configuración de Plupload de la siguiente manera:
$("#plupload_container").pluploadQueue({
runtimes: ''html5,gears,flash,silverlight,html4'',
flash_swf_url: ''../plupload/js/plupload.flash.swf'',
silverlight_xap_url: ''../plupload/js/plupload.silverlight.xap'',
filters: [
{ title: "Image files", extensions: "jpg,gif" },
{ title: "Zip files", extensions: "zip" },
{ title: "Document files", extensions: "doc,pdf,txt" }
]
});
... pero siento que me falta algo aquí que será necesario para subir al trabajo.
Supongo que mi pregunta principal es ¿cómo puedo llamar al código C # anterior para que la carga pueda comenzar? Tengo un formulario en una página llamada SubmitRequest.aspx
. Al hacer clic en ''Enviar'' en el formulario se obtiene lo siguiente:
$(''form'').submit(function (e) {
// 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)
$(''form'').submit();
});
uploader.start();
}
e.preventDefault();
}
});
... por lo que el cargador se inicia cuando se hace clic en ''Enviar'' y se cargan los archivos. Una vez hecho esto, el resto del formulario se envía. No entiendo cómo vincular este evento al código C # que manejará la carga a una carpeta TicketUploads
en el servidor.
Me disculpo por la publicación larga, pero agradecería cualquier ayuda :)
Aquí hay un ejemplo de VB de un archivo ashx para pluploader.
Gracias a @@ Darin Dimitrov ¿Quién sugirió esto? Es la mejor solución con muchos retrocesos como Silverlight, flash ... etc. ¡es mega!
No encontré ningún ejemplo de VB, así que lo convertí en uno mismo probado y funciona. Con fragmentación!
Para agregar un archivo ashx a su sitio web en VisualStudio. Haga clic derecho en el sitio web
sitio web> agregar nuevo elemento> controlador genérico
Esto es todo en una página sin necesidad de código detrás. Simplemente llame a esto desde el plugin pluplaod
<%@ WebHandler Language="VB" Class="upload" %>
Imports System
Imports System.IO
Imports System.Web
Public Class upload : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim chunk As Integer = If(context.Request("chunk") IsNot Nothing, Integer.Parse(context.Request("chunk")), 0)
Dim fileName As String = If(context.Request("name") IsNot Nothing, context.Request("name"), String.Empty)
Dim fileUpload As HttpPostedFile = context.Request.Files(0)
Dim uploadPath = context.Server.MapPath("~/uploads")
Using fs = New FileStream(Path.Combine(uploadPath, fileName), If(chunk = 0, FileMode.Create, FileMode.Append))
Dim buffer = New Byte(fileUpload.InputStream.Length - 1) {}
fileUpload.InputStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, buffer.Length)
End Using
context.Response.ContentType = "text/plain"
context.Response.Write("Success")
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class