2011-03-01 17 views
31

Estoy creando una aplicación de biblioteca de documentos con DocumentController que necesita cargar una imagen en miniatura de cada documento en la biblioteca. Quiero mantener el campo Cargar archivo en el mismo formulario Crear/Editar que los demás campos (Título, Descripción, Categoría, etc.).
El problema es que no estoy seguro si puedo mezclar o nido de las etiquetas de formulario paraMVC: Cómo publicar Subida de archivos y otros campos de formulario en una acción

Html.BeginForm("Create", "Document", FormMethod.Post, enctype = "multipart/form-data") 

y

Html.BeginForm() 

Mi opinión es la siguiente:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Publications.WebUI.Models.DocumentEditViewModel >" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Edit 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
    <fieldset> 
     <legend>Edit 
      <%= Html.Truncate(Model.Document.Title, 50)%></legend> 
     <%= Html.ValidationSummary(false) %> 
     <% using (Html.BeginForm()) 
      { %> 
     <div class="editor-label"> 
      <%= Html.LabelFor(model => model.Document.Title) %> 
     </div> 
     <div class="editor-field"> 
      <%= Html.HiddenFor(model => model.Document.DocumentId) %> 
      <%= Html.ValidationMessageFor(model => model.Document.Title) %> 
      <%= Html.TextBoxFor(model => model.Document.Title)%> 
     </div> 
     <div class="editor-label"> 
      <%= Html.LabelFor(model => model.Document.DocumentUrl)%> 
     </div> 
     <div class="editor-field"> 
      <%= Html.ValidationMessageFor(model => model.Document.DocumentUrl)%> 
      <%= Html.TextBoxFor(model => model.Document.DocumentUrl)%> 
     </div> 
     <div class="editor-label"> 
      <%= Html.LabelFor(model => model.Document.Description)%> 
     </div> 
     <div class="editor-field"> 
      <%= Html.ValidationMessageFor(model => model.Document.Description)%> 
      <%= Html.TextAreaFor(model => model.Document.Description) %> 
     </div> 
     <div class="editor-label"> 
      <%= Html.LabelFor(model => model.Document.ThumbnailUrl)%> 
     </div> 
     <div class="editor-field"> 
      <% using (Html.BeginForm("Create", "Document", 
        FormMethod.Post, new { enctype = "multipart/form-data" })) 
       {%> 
      <%= Html.ValidationMessageFor(model => model.Document.ThumbnailUrl)%> 
      <input name="uploadFile" type="file" /> 
      <% } %> 
     </div> 
     <div class="formActions"> 
      <div class="backNav"> 
       <%= Html.ActionLink("< Back to List", "Index") %> 
      </div> 
      <div class="submit"> 
       <input type="submit" value="Save" /> 
      </div> 
      <% } %> 
     </div> 
    </fieldset> 
</asp:Content> 

Mi controlador simplemente toma el modelo de documento y HttpPostedFileBase e intenta cargar el archivo en el servidor y guardar el documento en el repositorio

[HttpPost] 
public ActionResult Create(Document document, HttpPostedFileBase uploadFile) 
{ 

    if (ModelState.IsValid) 
    { 
     //Process file upload 
     //Update repository 

     } 

     return View("List"); 
    } 

Así que me pregunto si es posible hacer la carga del archivo y actualizar el repositorio en la misma acción y cómo debería estructurar mi vista para facilitar esto.

+0

creo que el código es correcto. :-) – AEMLoviji

+2

Destaca por cualquier persona tiene la muestra problema: el código de la pregunta original debería funcionar bien, solo una cosa que debe agregarse a su formulario es 'enctype =" multipart/form-data "'. – Jacky

Respuesta

34

He echado un vistazo al gran libro de Steve Sanderson (Pro ASP.NET MVC 2 Framework) y su aplicación de muestra Sports Store tiene un formulario de carga de archivos donde hay elementos de formulario estándar mezclados con una carga de archivo "multipart/form-data "elemento. Por lo tanto, parece que el tipo de varias partes es suficiente para todos los elementos de formulario en la página. Aunque la imagen cargada se guarda en el db, estoy seguro de que puedo hacer un archivo.SaveAs() dentro de la misma Acción. Gracias, Sr. Sanderson. Espera usted no me importaría que reproduce su código ...

VISTA

<asp:Content ContentPlaceHolderID="MainContent" runat="server"> 
    <h1>Edit <%= Model.Name %></h1> 

    <% using (Html.BeginForm("Edit", "Admin", FormMethod.Post, 
          new { enctype = "multipart/form-data" })) { %> 
     <%= Html.Hidden("ProductID") %> 
     <p> 
      Name: <%= Html.TextBox("Name") %> 
      <div><%= Html.ValidationMessage("Name") %></div> 
     </p> 
     <p> 
      Description: <%= Html.TextArea("Description", null, 4, 20, null) %> 
      <div><%= Html.ValidationMessage("Description") %></div> 
     </p> 
     <p> 
      Price: <%= Html.TextBox("Price") %> 
      <div><%= Html.ValidationMessage("Price") %></div> 
     </p> 
<p> 
    Category: <%= Html.TextBox("Category") %> 
    <div><%= Html.ValidationMessage("Category") %></div> 
</p> 
<p> 
    Image: 
    <% if(Model.ImageData == null) { %> 
     None 
    <% } else { %> 
     <img src="<%= Url.Action("GetImage", "Products", 
           new { Model.ProductID }) %>" /> 
    <% } %> 
    <div>Upload new image: <input type="file" name="Image" /></div>     
</p> 

<input type="submit" value="Save" /> &nbsp;&nbsp; 
     <%=Html.ActionLink("Cancel and return to List", "Index") %> 
    <% } %> 
</asp:Content> 

CONTROLADOR

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Edit(Product product, HttpPostedFileBase image) 
    { 
     if (ModelState.IsValid) { 
      if (image != null) { 
       product.ImageMimeType = image.ContentType; 
       product.ImageData = new byte[image.ContentLength]; 
       image.InputStream.Read(product.ImageData, 0, image.ContentLength); 
      } 
      productsRepository.SaveProduct(product); 
      TempData["message"] = product.Name + " has been saved."; 
      return RedirectToAction("Index"); 
     } 
     else // Validation error, so redisplay same view 
      return View(product); 
    } 
Cuestiones relacionadas