【问题标题】:unable to upload multiple db images with asp.net mvc无法使用 asp.net mvc 上传多个数据库图像
【发布时间】:2014-02-04 19:46:00
【问题描述】:

我正在尝试将几个数据库图像上传到 SQL Server 2008R2。我在 C# 中使用 ASP.NET MVC 3。发生的事情是我显示了图像,但问题是第二张图像显示为两次。所以它是重复的。我不确定为什么没有显示第一张图片。

我的 SubProductCategory4 表具有以下列(为简单起见)...

列名:Image1 和 Image2 具有 DataTypes varbinary(MAX),另一列名:ImageMimeType 具有 DataTypes varchar(50)。

我的控制器有以下 Create 方法的代码...

[HttpPost]
    public ActionResult Create([Bind(Exclude = "SubProductCategoryFourID")] SubProductCategory4 Createsubcat4, IEnumerable<HttpPostedFileBase> files, FormCollection collection)
    {
        if (ModelState.IsValid)
        {
           foreach (string inputTagName in Request.Files)
           {

     if (Request.Files.Count > 0) // tried Files.Count > 1 did 
                                          // not solve the problem
                    {
                        Createsubcat4.Image1 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]);
                        Createsubcat4.Image2 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]);
                        // var fileName = Path.GetFileName(inputTagName);
                        //var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                    }
                    // moved db.AddToSubProductCategory4(Createsubcat4);
                    // here  but did not solve the problem
           }
            db.AddToSubProductCategory4(Createsubcat4);
            db.SaveChanges();
            return RedirectToAction("/");
        }


   //someother code

        return View(Createsubcat4);
    } 

GetImage 方法...

public FileResult GetImage(int id)
    {
        const string alternativePicturePath = @"/Content/question_mark.jpg";
        MemoryStream stream;
        MemoryStream streaml;

        SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault();

        if ((z != null && z.Image1 != null) && (z != null && z.Image2 != null))
        {

                stream = new MemoryStream(z.Image1);
                streaml = new MemoryStream(z.Image2);
        }

        else
        {
              var path = Server.MapPath(alternativePicturePath);

             foreach (byte item in Request.Files)
              { 
                HttpPostedFileBase file = Request.Files[item];
                if (file.ContentLength == 0)
                {
                    continue;
                }
             }

            stream = new MemoryStream();
            var imagex = new System.Drawing.Bitmap(path);
            imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            stream.Seek(0, SeekOrigin.Begin);

           /* streaml = new MemoryStream();
            var imagey = new System.Drawing.Bitmap(path);
            imagey.Save(streaml, System.Drawing.Imaging.ImageFormat.Jpeg);
            streaml.Seek(0, SeekOrigin.Begin);*/
        }

       return new FileStreamResult(stream,"image/jpg");

    }

文件处理程序.cs

public class FileHandler
{
    public byte[] uploadedFileToByteArray(HttpPostedFileBase file)
    {
        int nFileLen = file.ContentLength;
        byte[] result = new byte[nFileLen];

        file.InputStream.Read(result, 0, nFileLen);

        return result;
    }

}

create.cshtml...

     @using (Html.BeginForm("Create", "ProductCategoryL4", "GetImage",  
     FormMethod.Post, new { enctype = "multipart/form-data" }))    
      //some code then...
     <div class="editor-field">
     @Html.EditorFor(model => model.Image1)
    <input type="file" id="fileUpload1" name="fileUpload1" size="23"/>
     @Html.ValidationMessageFor(model => model.Image1)
    </div>

     <div class="editor-field">
     @Html.EditorFor(model => model.Image2)
     <input type="file" id="fileUpload2" name="fileUpload2" size="23"/>
     @Html.ValidationMessageFor(model => model.Image2)
    </div>

index.cshtml...

<img src="@Url.Action("GetImage", "ProductCategoryL4", new { id =   
item.SubProductCategoryFourID })" alt="" height="100" width="100" /> 
</td>
  <td>
    <img src="@Url.Action("GetImage", "ProductCategoryL4", new { id = 
    item.SubProductCategoryFourID })" alt="" height="100" width="100" /> 
  </td>

我在 C# 中使用 VS2010、ASP.NET MVC3 和 SQL Server 2008R2。在此先感谢,但请仅在您知道答案的情况下回复。如果有更好的方法,请告诉我。

【问题讨论】:

    标签: c# asp.net-mvc-3


    【解决方案1】:

    列出的代码循环遍历文件,并且对于每个文件,都将Image1 和Image2 设置为相同的东西。当您上传 2 个文件时,它们都显示为图像 2,因为这是应用于两个字段的最后一张图像。

    尝试用类似这样的方式替换循环,如果有足够的图像,则一次设置一个字段。

    FileHandler fh = new FileHandler();
    
    if (Request.Files.Count > 0)
    {
        Createsubcat4.Image1 = fh.uploadedFileToByteArray(Request.Files[0]);
    }
    
    if (Request.Files.Count > 1)
    {
        Createsubcat4.Image2 = fh.uploadedFileToByteArray(Request.Files[1]);
    }
    
    db.AddToSubProductCategory4(Createsubcat4);
    

    如果您以后需要打开它以允许更多图像,您需要将 Image1 和 Image2 字段替换为图像集合,然后再次使用循环将每个图像添加到上传的文件集合。像这样的:

    FileHandler fh = new FileHandler();
    
    foreach (HttpPostedFileBase uploadedImage in Request.Files)
    {
        Createsubcat4.Images.Add(fh.uploadedFileToByteArray(uploadedImage));
    }
    
    db.AddToSubProductCategory4(Createsubcat4);
    db.SaveChanges();
    

    编辑:

    现在您已正确保存图像,您需要再次查看您的 GetImage 操作。您会注意到您正确地将两个文件加载到内存中,但是当您指定操作结果 (return new FileStreamResult(stream,"image/jpg");) 时,您只会返回第一个流。您需要一种在请求时返回第二个流的方法。有几种方法可以解决此问题,添加另一个输入参数以指定要加载的图像或创建仅返回第二个图像的第二个操作。

    要创建两个操作设置,您的代码应如下所示:

    public ActionResult GetImage1(int id)
    {
        const string alternativePicturePath = @"/Content/question_mark.jpg";
        MemoryStream stream;
    
        SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault();
    
        if (z != null && z.Image1 != null)
        {
            stream = new MemoryStream(z.Image1);
        }
        else
        {
            var path = Server.MapPath(alternativePicturePath);
    
            stream = new MemoryStream();
            var imagex = new System.Drawing.Bitmap(path);
            imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            stream.Seek(0, SeekOrigin.Begin);
        }
    
        return new FileStreamResult(stream,"image/jpg");
    }
    
    public ActionResult GetImage2(int id)
    {
        const string alternativePicturePath = @"/Content/question_mark.jpg";
        MemoryStream stream;
    
        SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault();
    
        if (z != null && z.Image2 != null) // the difference is here
        {
            stream = new MemoryStream(z.Image2); // the difference is also here
        }
        else
        {
            var path = Server.MapPath(alternativePicturePath);
    
            stream = new MemoryStream();
            var imagex = new System.Drawing.Bitmap(path);
            imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            stream.Seek(0, SeekOrigin.Begin);
        }
    
        return new FileStreamResult(stream,"image/jpg");
    }
    

    这些函数几乎是相同的,可以很容易地变成 1,它接受一个参数来选择要加载的图像。

    public ActionResult GetImage(int id, int? imageNum)
    {
        imageNum = imageNum ?? 0;
    
        const string alternativePicturePath = @"/Content/question_mark.jpg";
        MemoryStream stream;
    
        SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault();
    
        byte[] imageData = null;
    
        if (z != null)
        {
            imageData = imageNum == 1 ? z.Image1 : imageNum == 2 ? z.Image2 : null;
        }
    
        if (imageData != null)
        {
            stream = new MemoryStream(imageData);
        }
        else
        {
            var path = Server.MapPath(alternativePicturePath);
    
            stream = new MemoryStream();
            var imagex = new System.Drawing.Bitmap(path);
            imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            stream.Seek(0, SeekOrigin.Begin);
        }
    
        return new FileStreamResult(stream,"image/jpg");
    }
    

    此函数会将imageNum 指定为查询参数,例如:

    http://www.mydomain.com/controllerName/GetImage/{id}?imageNum={imageNum}

    【讨论】:

    • @NickLarsen - 恐怕也没有解决问题。您提供的代码,第一张图片显示为两次。所以它是重复的。
    • @DiscoDude:所以现在您正确保存了图片,并且您的GetImage 操作需要更新。更新我的回复以帮助您获得更多帮助。
    • @NickLarsen - 你能澄清一下 foreach 循环吗?数据库列?因为我收到此错误消息...“不包含'Images'的定义,并且找不到接受第一个类型参数的扩展方法'Images'(您是否缺少 using 指令或程序集引用?)”
    • @NickLarsen:同样在没有 foreach 循环的情况下,我收到以下错误消息...参数字典包含方法'的不可为空类型'System.Int32'的参数'imageNum'的空条目'MyApplication1.Server.ProductCategoryL4Controller' 中的 System.Web.Mvc.FileResult GetImage(Int32, Int32)'。可选参数必须是引用类型、可空类型或声明为可选参数。参数名称:参数
    • 现在图像可以正常显示了。现在我希望我可以上传几个数据库图像。我没有机会从您提供的代码中知道,所以非常感谢。代表我喝一品脱啤酒。以您的方式发送积分。我希望这个踏板对其他人有用
    【解决方案2】:

    我认为你的问题可能在这个循环中。

    foreach (string inputTagName in Request.Files)
    {
        if (Request.Files.Count > 0)
        {
            Createsubcat4.Image1 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]);
            Createsubcat4.Image2 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]);
            // var fileName = Path.GetFileName(inputTagName);
            //var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
         }
    }
    db.AddToSubProductCategory4(Createsubcat4);
    

    Request.Files.Count &gt; 0 应该始终为真,因为您正在遍历文件列表。然而,真正的问题是,在这个循环中,您使用每个文件覆盖 Createsubcat4 的属性,然后在使用最后一个文件设置属性后,这就是发送到数据库的内容。

    如果您尝试将多条记录添加到数据库中(每个图像一条),您需要在循环中移动 AddToSubProductCategory4。如果您尝试将两个图像添加到该记录中,我建议您按名称分配每个图像,并跳过 foreach 循环。

    【讨论】:

    • 在发布这个问题之前,我确实在循环中移动了 AddToSubProductCategory4,但恐怕它不能解决问题。我在代码上添加了一些 cmets。还将 Request.Files.Count > 0 更改为 1,这也没有解决问题。还有其他建议吗?
    • @NickLarsen - 你能告诉我什么和为什么吗?用于公共 ActionResult GetImage(int id, int?imageNum) 方法。
    • @DiscoDude:它使它们可以为空整数,以便在未指定参数时有一些指示。否则每次都会默认为 0,当用户指定 imageNum 为 0 时,您会遇到一个模棱两可的情况。
    猜你喜欢
    • 2014-11-04
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 2018-08-28
    • 2015-06-19
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    相关资源
    最近更新 更多