2010-02-25 5 views
42

¿Qué tengo?Publicar Atrás no funciona después de escribir archivos para responder en ASP.NET

Tengo una página ASP.NET que permite al usuario descargar el archivo a con un clic de botón. El usuario puede seleccionar el archivo que desea de una lista de archivos disponibles (RadioButtonList) y hacer clic en el botón de descarga para descargarlo. (No debería proporcionar un enlace para cada archivo que se puede descargar, este es el requisito).

¿Qué es lo que quiero?

Deseo que el usuario descargue varios archivos uno por uno seleccionando el botón de opción requerido y haciendo clic en el botón.

¿Qué problema estoy enfrentando?

Puedo descargar el archivo por primera vez correctamente. Pero, después de la descarga, si selecciono algún otro archivo y hago clic en el botón para descargarlo, haga clic en evento del botón no se publicará y el segundo archivo no se descargará.

uso el siguiente código en el evento de clic de botón:

protected void btnDownload_Click(object sender, EventArgs e) 
{ 
    string viewXml = exporter.Export(); 
    Response.Clear(); 
    Response.AddHeader("Content-Disposition", "attachment; filename=views.cov"); 
    Response.AddHeader("Content-Length", viewXml.Length.ToString()); 
    Response.ContentType = "text/plain"; 
    Response.Write(viewXml); 
    Response.End(); 
} 

Estoy haciendo algo mal aquí?

El mismo problema se puede replicar en IE6, IE7 y Chrome. Creo que este problema es independiente del navegador.

+0

Si tiene un formulario habilitado para Ajax (o control), puede ser que el javascript Ajax esté mezclado o bloqueado ya que devolvió un documento diferente en lugar de devolver lo que esperaba Javascript (información de viewstate más html actualizado que entra el panel de actualización). Consulte también http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/55136e4e-e1f7-4a79-9b75-be09cd5594c2/ –

Respuesta

55

tenía este mismo problema con SharePoint. Tengo un botón en la página que envía un archivo y luego de hacer clic en el botón, el resto del formulario no responde. Resulta que es una cosa compartida que establece la variable _spFormOnSubmitCalled en true para evitar más envíos. Cuando enviamos un archivo, esto no actualiza la página, por lo que debemos volver a establecer manualmente esta variable en falso.

En su botón en el elemento web configure OnClientClick a una función en su javascript para la página.

<asp:Button ID="generateExcel" runat="server" Text="Export Excel" 
OnClick="generateExcel_Click" CssClass="rptSubmitButton" 
OnClientClick="javascript:setFormSubmitToFalse()" /> 

Luego en el javascript tengo esta función.

function setFormSubmitToFalse() { 
    setTimeout(function() { _spFormOnSubmitCalled = false; }, 3000); 
    return true; 
} 

La pausa de 3 segundos que encontré fue necesaria porque de lo contrario estaba configurando la variable antes de establecerla en el punto compartido. De esta forma, dejé que sharepoint lo configurara normalmente y luego lo configuré nuevamente en falso justo después.

+0

Conocía este bocado de información en el pasado, pero lo olvidé por completo. Gracias por ahorrarme horas recordándome. – DaleyKD

+0

funcionó como un encanto para mi biblioteca de documentos sharepoint> problema de descarga de documentos. ¡¡¡Tres hurras!!! – shoab

4

Offhand, lo que estás haciendo debería funcionar. He hecho con éxito algo similar en el pasado, aunque utilicé un repetidor y LinkButtons.

La única cosa que puedo ver que es diferente es que se está utilizando en lugar de Response.Write()Response.OutputStream.Write(), y que usted está escribiendo texto en lugar de binario, pero dada la ContentType que ha especificado, no debería ser un problema. Además, llamo al Response.ClearHeaders() antes de enviar información, y Response.Flush() después (antes de llamar al Response.End()).

Si se va a ayudar, he aquí una versión aséptica de lo que funciona bien para mí:

// called by click handler after obtaining the correct MyFileInfo class. 
private void DownloadFile(MyFileInfo file) 
{ 
    Response.Clear(); 
    Response.ClearHeaders(); 
    Response.ContentType = "application/file"; 
    Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.FileName + "\""); 
    Response.AddHeader("Content-Length", file.FileSize.ToString()); 
    Response.OutputStream.Write(file.Bytes, 0, file.Bytes.Length); 
    Response.Flush(); 
    Response.End();   
} 

Es posible que desee considerar la posibilidad de transferir el archivo de una manera binaria, tal vez llamando System.Text.Encoding.ASCII.GetBytes(viewXml); y pasando el resultado de esa a Response.OutputStream.Write().

Modificar su código levemente:

protected void btnDownload_Click(object sender, EventArgs e) 
{ 
    string viewXml = exporter.Export(); 
    byte [] bytes = System.Text.Encoding.ASCII.GetBytes(viewXml); 
    // NOTE: you should use whatever encoding your XML file is set for. 
    // Alternatives: 
    // byte [] bytes = System.Text.Encoding.UTF7.GetBytes(viewXml); 
    // byte [] bytes = System.Text.Encoding.UTF8.GetBytes(viewXml); 

    Response.Clear(); 
    Response.ClearHeaders(); 
    Response.AddHeader("Content-Disposition", "attachment; filename=views.cov"); 
    Response.AddHeader("Content-Length", bytes.Length.ToString()); 
    Response.ContentType = "application/file"; 
    Response.OutputStream.Write(bytes, 0, bytes.Length); 
    Response.Flush(); 
    Response.End(); 
} 
+0

Gracias, Randolpho. Sin suerte con el código alterado también. Se está comportando igual :( – Vijay

+0

Hmm ... bueno, estoy perplejo. Como dije, lo que tengo funciona bien. ¿Es posible que sea algo que haga en su código antes de que se llame al controlador de clics? Si puede, intenta publicar la página completa y el código subyacente. – Randolpho

+0

El 'Response.ClearHeaders()' parecía ser crítico en mi caso. Gracias Randolpho. –

3

Quitar Response.End() y dejar que la respuesta al final de forma natural dentro del ecosistema de ASP.NET.

Si eso no funciona, recomendaría poner el botón en un <form> por separado y publicar los datos requeridos en un controlador HTTP por separado. Configure el controlador HTTP para exportar el XML en lugar de una página web.

+0

Inicialmente no había incluido 'Response.End()'. No funcionaba entonces como bien! – Vijay

+1

Hmmm. Bueno, tal vez puede tratar de poner el botón en un '

' separado y publicar los datos necesarios en un controlador HTTP diferente que está configurado para exportar el XML? –

+0

Además, debe especificar una codificación de contenido como 'Respuesta .ContentEncoding = Encoding.UTF8' –

4

Una manera simple de hacerlo sin eliminar Response.End es agregar js del lado del cliente para actualizar la página. Agregue el js a la propiedad de clic de su botón en el cliente.

p. Ej.

onclientclick="timedRefresh(2000)" 

then in your html.. 

    <script type="text/JavaScript"> 
    <!-- 
    function timedRefresh(timeoutPeriod) { 
     setTimeout("location.reload(true);",timeoutPeriod); 
    } 
    // --> 

3

Tuve el mismo problema. La función para realizar Response.Writer simple ("") en el evento Click Click en la página aspx nunca se activaba.

Método en la clase:

public test_class() 
{ 
    public test_class() { } 

    public static void test_response_write(string test_string) 
    { 
     HttpContext context = HttpContext.Current; 
     context.Response.Clear(); 
     context.Response.Write(test_string); 
     context.Response.End();     
    } 
} 

página ASPX:

protected void btn_test_Click(object sender, EventArgs e) 
{ 
    test_class.test_response_write("testing...."); 
} 

Mientras yo estaba tratando de encontrar la razón, me acaba de llamar misma función en Page_Load caso funcionó.

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
    { 
     test_class.test_response_write("testing...."); 
    } 
} 

Investigando el tema descubrí que de páginas principales del cuerpo de la página aspx estaba bajo <asp:UpdatePanel>.

Lo eliminé y funcionó en Button_Click Evento. Te recomendaría que lo revises también.

Cuestiones relacionadas