MVC:如何将文件上传和其他表单字段发布到一个操作中 [英] MVC: How to post File Upload and other form fields to one action

查看:22
本文介绍了MVC:如何将文件上传和其他表单字段发布到一个操作中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个带有 DocumentController 的文档库应用程序,它需要上传库中每个文件的缩略图.我想将文件上传字段保留在与其他字段(标题、说明、类别 ID 等)相同的创建/编辑表单上.
问题是我不确定是否可以混合或嵌套

的表单标签

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

Html.BeginForm()

我的观点如下:

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Publications.WebUI.Models.文档编辑视图模型 >"%><asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">编辑</asp:内容><asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"><字段集><传说>编辑<%= Html.Truncate(Model.Document.Title, 50)%></legend><%= Html.ValidationSummary(false)%><% 使用 (Html.BeginForm()){%><div class="editor-label"><%=Html.LabelFor(model=>model.Document.Title)%>

<div class="editor-field"><%=Html.HiddenFor(model=>model.Document.DocumentId)%><%=Html.ValidationMessageFor(model=>model.Document.Title)%><%=Html.TextBoxFor(model=>model.Document.Title)%>

<div class="editor-label"><%=Html.LabelFor(model=>model.Document.DocumentUrl)%>

<div class="editor-field"><%=Html.ValidationMessageFor(model=>model.Document.DocumentUrl)%><%= Html.TextBoxFor(model => model.Document.DocumentUrl)%>

<div class="editor-label"><%=Html.LabelFor(model=>model.Document.Description)%>

<div class="editor-field"><%=Html.ValidationMessageFor(model=>model.Document.Description)%><%=Html.TextAreaFor(model=>model.Document.Description)%>

<div class="editor-label"><%=Html.LabelFor(model=>model.Document.ThumbnailUrl)%>

<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 class="formActions"><div class="backNav"><%= Html.ActionLink("<返回列表", "索引") %>

<div class="提交"><input type="submit" value="保存"/>

<%}%>

</fieldset></asp:内容>

我的控制器只接受文档模型和 HttpPostedFileBase 并尝试将文件上传到服务器并将文档保存到存储库

 [HttpPost]公共 ActionResult 创建(文档文档,HttpPostedFileBase 上传文件){如果(模型状态.IsValid){//处理文件上传//更新仓库}返回视图(列表");}

所以我想知道是否可以在同一操作上进行文件上传和更新存储库,以及我应该如何构建我的视图以促进这一点.

解决方案

我查看了 Steve Sanderson 的好书(Pro ASP.NET MVC 2 Framework),他的 Sports Store 示例应用程序有一个文件上传表单,其中有标准表单元素与文件上传multipart/form-data"元素混合.所以看起来 multipart 类型足以满足页面上的所有表单元素.虽然上传的图像被保存在数据库中,但我确信我可以在同一个操作中执行 file.SaveAs() .谢谢桑德森先生.希望你不介意我复制你的代码...

查看

 <h1>编辑<%=模型.名称%></h1><% using (Html.BeginForm("Edit", "Admin", FormMethod.Post,new { enctype = "multipart/form-data" })) { %><%= Html.Hidden("ProductID") %><p>名称:<%= Html.TextBox("Name") %><div><%= Html.ValidationMessage("Name") %></div></p><p>说明:<%= Html.TextArea("Description", null, 4, 20, null) %><div><%=Html.ValidationMessage("Description")%></div></p><p>价格:<%= Html.TextBox("Price") %><div><%= Html.ValidationMessage("Price") %></div></p><p>类别:<%= Html.TextBox("Category") %><div><%= Html.ValidationMessage("Category") %></div></p><p>图片:<% if(Model.ImageData == null) { %>没有任何<% } else { %><img src="<%= Url.Action("GetImage", "Products",new { Model.ProductID }) %>"/><%}%><div>上传新图片:<input type="file" name="Image"/></div></p><input type="submit" value="保存"/>&nbsp;&nbsp;<%=Html.ActionLink("取消并返回列表", "索引") %><%}%></asp:内容>

控制器

 [AcceptVerbs(HttpVerbs.Post)]公共 ActionResult 编辑(产品产品,HttpPostedFileBase 图像){如果(ModelState.IsValid){如果(图像!= 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 + "已保存.";return RedirectToAction("索引");}else//验证错误,所以重新显示相同的视图返回视图(产品);}

I am creating a document library application with a DocumentController that needs to upload a thumbnail image of each doument in the library. I want to keep the File Upload field on the same Create/Edit form as the other fields (Title, Description, CategoryId etc).
The problem is I'm not sure if I can mix or nest the form tags for

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

and

Html.BeginForm()

My view is as follows:

 <%@ 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>

My controller just takes the Document model and HttpPostedFileBase and tries to upload the file to the server and save the Document to the repository

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

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

      }

       return View("List");
  }

So I'm wondering if it is possible to do the file upload and update the repository on the same action and how should I structure my View to facilitate this.

解决方案

I had a look in Steve Sanderson's great book (Pro ASP.NET MVC 2 Framework) and his Sports Store sample application has a file upload form where there are standard form elements mixed with a file upload "multipart/form-data" element. So it looks like the multipart type suffices for all form elements on the page. Although the uploaded image is being saved in the db I'm sure I can do a file.SaveAs() within the same Action. Thanks Mr. Sanderson. Hope you dont mind me reproducing your code...

VIEW

    <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>

CONTROLLER

    [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);
    }

这篇关于MVC:如何将文件上传和其他表单字段发布到一个操作中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆