Cómo escribir "Html.BeginForm" en Razor

133

Si escribo así:

form action = "Images" method = "post" enctype = "multipart / form-data"

funciona.

Pero en Razor con '@' no funciona. ¿Cometí algún error?

@using (Html.BeginForm("Upload", "Upload", FormMethod.Post, 
                             new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)

    <fieldset>

        Select a file <input type="file" name="file" />
        <input type="submit" value="Upload" />

    </fieldset>
}

Mi controlador se ve así:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload() 
{
    foreach (string file in Request.Files)
    {
        var uploadedFile = Request.Files[file];
        uploadedFile.SaveAs(Server.MapPath("~/content/pics") + 
                                      Path.GetFileName(uploadedFile.FileName));
    }

    return RedirectToAction ("Upload");
}
kk-dev11
fuente
¿La acción es realmente "imágenes" o es "Cargar / Cargar"?
J. Steen
En realidad tengo dos controladores. el controlador de imagen con la acción 'imagen' .. y el controlador de carga 'con la acción de carga ..
kk-dev11

Respuestas:

200

El siguiente código funciona bien:

@using (Html.BeginForm("Upload", "Upload", FormMethod.Post, 
                                      new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        Select a file <input type="file" name="file" />
        <input type="submit" value="Upload" />
    </fieldset>
}

y genera como se esperaba:

<form action="/Upload/Upload" enctype="multipart/form-data" method="post">    
    <fieldset>
        Select a file <input type="file" name="file" />
        <input type="submit" value="Upload" />
    </fieldset>
</form>

Por otro lado, si está escribiendo este código dentro del contexto de otra construcción del lado del servidor, como por ejemplo, ifo foreachdebe eliminar @antes del using. Por ejemplo:

@if (SomeCondition)
{
    using (Html.BeginForm("Upload", "Upload", FormMethod.Post, 
                                      new { enctype = "multipart/form-data" }))
    {
        @Html.ValidationSummary(true)
        <fieldset>
            Select a file <input type="file" name="file" />
            <input type="submit" value="Upload" />
        </fieldset>
    }
}

En lo que respecta al código del lado del servidor, aquí se explica cómo proceder :

[HttpPost]
public ActionResult Upload(HttpPostedFileBase file) 
{
    if (file != null && file.ContentLength > 0) 
    {
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(Server.MapPath("~/content/pics"), fileName);
        file.SaveAs(path);
    }
    return RedirectToAction("Upload");
}
Darin Dimitrov
fuente
1
Gracias. Mire el controlador que actualicé en mi pregunta. No funciona con el código de la maquinilla de afeitar ..
kk-dev11
2
@ user1076915, ¿qué significa que no funciona ? Podrías ser un poco más específico. He actualizado mi respuesta con un código de muestra de cómo podría verse la acción de su controlador. Si no puede obtener el archivo cargado en la acción del controlador, eso podría significar que tiene <form>etiquetas anidadas (que no están permitidas en HTML) o puede estar usando algún javascript que secuestra el envío normal del formulario y hace una solicitud AJAX que no No funciona con cargas de archivos.
Darin Dimitrov
Usé su acción de controlador y la maquinilla de afeitar '@using' ... pero muestra -> Descripción: HTTP 404. El recurso que está buscando (o una de sus dependencias) podría haberse eliminado, cambiado su nombre o está temporalmente no disponible Revise la siguiente URL y asegúrese de que esté escrita correctamente.
kk-dev11
@ user1076915, ¿cuándo recibe este mensaje de error? ¿Cuándo desea procesar el formulario de carga o cuando lo envía? En el primer caso, asegúrese de que tiene una GETacción de carga que servirá a la Upload.cshtmlvista que contiene este código: public ActionResult Upload() { return View(); }. Así que asegúrese de tener un controlador llamado que UploadControllercontenga las dos acciones de Carga: una para entregar el formulario y la otra para procesar el envío.
Darin Dimitrov
2
Funciona, pero en un contexto POST sugiero agregar: @ Html.AntiForgeryToken ();
Frédéric De Lène Mirouze