【问题标题】:Can't add file upload capability to generated MVC3 page无法将文件上传功能添加到生成的 MVC3 页面
【发布时间】:2012-04-09 01:05:52
【问题描述】:

我是 MCV 新手,正在学习 MVC3。我创建了一个模型和一个控制器,并为我生成了视图。生成的代码对我来说非常有意义。我想修改生成的视图和控制器,以便在“创建”新记录时可以上传文件。有很多关于如何做到这一点的好信息。具体来说,我试过这个:http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx

问题是即使我选择了一个文件(不大)并提交,请求中也没有文件。即 Request.Files.Count 为 0。

如果我在同一个项目(无模型)中从头开始创建控制器和视图,则该示例可以正常工作。我只是无法将该功能添加到生成的页面中。基本上,我正在尝试让 Create 操作也发送文件。例如,创建一个新的产品条目并发送图片。

示例创建视图:

@model Product.Models.Find

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm("Create", "Find", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.ValidationSummary(true)
<fieldset>
    <legend>Find</legend>

        <input type="file" id="file" /> 


    <div class="editor-label">
        @Html.LabelFor(model => model.Title)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Title)
        @Html.ValidationMessageFor(model => model.Title)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Description)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Description)
        @Html.ValidationMessageFor(model => model.Description)
    </div>

    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

示例控制器:

    [HttpPost]
    public ActionResult Create(Product product)
    {
        if (ModelState.IsValid)
        {
            if (Request.Files.Count > 0 && Request.Files[0] != null)
            {
                //Not getting here
            }

            db.Products.Add(product);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(find);
    }

这将很好地创建记录,但没有与请求关联的文件。

我也尝试过这样的控制器操作:

    [HttpPost]
    public ActionResult Create(HttpPostedFileBase file)
    {
        if (file.ContentLength > 0)
        {
            //Not getting here
        }

        return RedirectToAction("Index");
    }

我想知道您是否不能在发布表单字段的同时发布文件?如果是这样,创建新记录并将图片(或其他文件)与之关联的模式是什么?

谢谢

【问题讨论】:

    标签: asp.net-mvc-3


    【解决方案1】:

    创建一个具有处理图像和产品细节的属性的 ViewModel

    public class ProductViewModel
    {
     public string ImageURL { set;get;}
     public string Title { set;get;}
     public string Description { set;get;}
    }
    

    然后在您的 HTTPGET Action 方法中,将此 ViewModel 对象返回给您的强类型视图

     public ActionResult Create()
     {
            ProductViewModel objVM = new ProductViewModel();
            return View(objVM);
     }
    

    在你的视野中

    @model ProductViewModel 
    <h2>Add Product</h2>
     @using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
      @Html.TextBoxFor(m => m.Title) <br/>
      @Html.TextBoxFor(m => m.Description ) <br/>
      <input type="file" name="file" />
      <input type="submit" value="Upload"  />
      @Html.HiddenFor(m => m.ImageURL )
    }
    

    现在在您的 HttpPost 操作方法中,接受这个 ViewModel 和 File

    [HttpPost]
    public ActionResult Create(HttpPostedFileBase file, ProductViewModel objVM)
    {
      if(file==null)
      {
         return View("Create",objVM);
      }
     else
     {
        //You can check ModeState.IsValid if you have to check any model validations and do further processing with the data here.
        //Now you have everything here in your parameters, you can access those and save
     }        
    }
    

    【讨论】:

    • 这与我已经拥有的非常接近,但我将我的 HttpPost 从“创建(HttpPostedFileBase 文件)”更新为“创建(HttpPostedFileBase 文件,ProductViewModel objVM)”,我的产品确实在 objVM 中出现,但是“文件”仍然为空。听起来我应该能够做到这一点,但文件始终为空。我知道文件不是太大,我正在设置 enctype = "multipart/form-data"。不知道为什么它是空的。
    • @FeatureCreep : 给你name="file"文件上传输入。
    • 噢!我错过了。我正在设置 id 一个非名称。是的,就是这样。非常感谢!
    【解决方案2】:

    您必须为Product(可能是ProductViewModel)创建一个ViewModel,并添加一个与表单字段同名的HttpPostedFileBase字段,并在操作中使用它而不是Product控制器。

    ViewModel 只不过是用于特定视图的模型。大多数时候,需要额外的数据来生成视图或在控制器动作上分解和形成模型。

    public ProductViewModel
    {
        public string Cod { get; set; }
        // All needed fields goes here
    
        public HttpPostedFileBase File{ get; set; }
    
        /// Empty constructor and so on ...
    }
    

    【讨论】:

    • 这就是我认为我在帖子底部的另一个示例所做的事情。在这种情况下,“文件”为空。
    • 对不起,我错过了这一点。忘记那个。查看 Shyju 的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    相关资源
    最近更新 更多