2010-02-10 62 views
13

La configuración:ASP.NET MVC Controller fileContent ActionResult llamada a través de AJAX

El controlador contiene un método public ActionResult SaveFile() que devuelve un FileContentResult.

Lo que funciona:

la vista contiene un formulario, que se somete a esta acción. El resultado es este cuadro de diálogo: enter image description here

lo que no funciona:

la vista contiene algo de JavaScript que hacer una llamada AJAX para la misma acción del controlador donde la forma sería publicar. En lugar de activar el cuadro de diálogo mencionado anteriormente, o incluso la función de éxito AJAX, la respuesta activa la función de error AJAX y el XMLHttpRequest.responseText contiene la respuesta del archivo.

Lo que tiene que hacer:

hacer la petición para el archivo usando AJAX, y terminar con el mismo resultado que al enviar un formulario. ¿Cómo puedo hacer que la solicitud AJAX proporcione el diálogo que muestra el envío de un formulario?

+0

Por qué no puedes simplemente utilizar la llamada no ajax? – LukLed

+0

Puedo, pero quiero hacer algún otro procesamiento en la función javaScript una vez que finalice la operación de salvar, como desbloquear el formulario, que bloqueé antes de guardar. – Rick

+0

OK, por lo que primero puede llamar a ajax SaveFile. SaveFile devolverá verdadero/falso. Cuando devuelve verdadero, llama a GET que no es Ajax para obtener el archivo. – LukLed

Respuesta

16

Aquí hay un ejemplo rápido que inventé. Este es el concepto del que hablaba LukLed al llamar a SaveFile, pero no devuelve el contenido del archivo a través de ajax y en su lugar redirige a la descarga.

Aquí está el código de la vista:

<script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script> 
<script type="text/javascript"> 
    $(function() { 
     // hide form code here 

     // upload to server 
     $('#btnUpload').click(function() { 
      $.ajax({ 
       type: 'POST', 
       dataType: 'json', 
       url: '<%= Url.Action("SaveFile", "Home") %>', 
       success: function(fileId) { 
        window.location = '<%= Url.Action("DownloadFile", "Home") %>?fileId=' + fileId; 
       }, 
       error: function() { 
        alert('An error occurred uploading data.'); 
       } 
      }); 
     }); 
    }); 
</script> 

<% using (Html.BeginForm()) { %> 

    <div>Field 1: <%= Html.TextBox("field1") %></div> 

    <div>Field 2: <%= Html.TextBox("field2") %></div> 

    <div>Field 3: <%= Html.TextBox("field3") %></div> 

    <button id="btnUpload" type="button">Upload</button> 

<% } %> 

Aquí está el código del controlador:

[HandleError] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    public JsonResult SaveFile(string field1, string field2, string field3) 
    { 
     // save the data to the database or where ever 
     int savedFileId = 1; 

     // return the saved file id to the browser 
     return Json(savedFileId); 
    } 

    public FileContentResult DownloadFile(int fileId) 
    { 
     // load file content from db or file system 
     string fileContents = "field1,field2,field3"; 

     // convert to byte array 
     // use a different encoding if needed 
     var encoding = new System.Text.ASCIIEncoding(); 
     byte[] returnContent = encoding.GetBytes(fileContents); 

     return File(returnContent, "application/CSV", "test.csv"); 
    } 

    public ActionResult About() 
    { 
     return View(); 
    } 
} 
+0

Nate, gracias por brindarnos un ejemplo tan detallado. Lo agradezco y también le agradezco a LukLed por tratar diligentemente de explicar su solución. El punto que no se hundía era que la primera llamada preparaba los datos para ser salvados, y la segunda llamada realizaba la descarga. – Rick

+0

He estado allí antes de golpear mi cabeza contra la pared diciendo WTF para mí tratando de entender, sin preocupaciones. Encantado de ayudar. –

Cuestiones relacionadas