简体   繁体   English

无法使用 asp.net mvc 上传多个数据库图像

[英]unable to upload multiple db images with asp.net mvc

I am trying to upload several db images onto the SQL Server 2008R2.我正在尝试将多个数据库图像上传到 SQL Server 2008R2。 I am using ASP.NET MVC 3 in C#. What is happening is that I getting the images displayed but the problem is that the second image is being displayed as twice.我在 C# 中使用 ASP.NET MVC 3。发生的事情是我显示了图像,但问题是第二张图像显示了两次。 So it is duplicate.所以它是重复的。 I am not sure why the first image is not being displayed.我不确定为什么没有显示第一张图片。

My SubProductCategory4 Table has the following columns (for simplicity sake)...我的 SubProductCategory4 表包含以下列(为简单起见)...

Column Names: Image1 and Image2 has DataTypes varbinary(MAX), another column Name: ImageMimeType has DataTypes varchar(50).列名:Image1 和 Image2 的数据类型为 varbinary(MAX),另一列名称:ImageMimeType 的数据类型为 varchar(50)。

My Controller has the following code for Create method...我的 Controller 具有以下创建方法代码...

[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 method...获取图像方法...

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");

    }

FileHandler.cs文件处理程序.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...创建.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...索引.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>

I am using using VS2010, ASP.NET MVC3 in C# with SQL Server 2008R2.我在 C# 中使用 VS2010、ASP.NET MVC3 和 SQL Server 2008R2。 Thanks in advance but please only respond if you know the answer.在此先感谢,但请仅在您知道答案的情况下回复。 If there is a better way of doing this please let me know.如果有更好的方法,请告诉我。

The code that is listed is looping through the files, and for each one, setting both Image1 and Image2 to be the same thing. 列出的代码遍历文件,并且对于每个文件,将Image1Image2设置为同一对象。 When you upload 2 files, they are both showing up as image 2 because that was the last image applied to both fields. 当您上传2个文件时,它们都显示为图像2,因为这是应用于这两个字段的最后一个图像。

Try replacing the loop with something more like this, which sets the fields one at a time if there are enough images. 尝试用类似这样的方式替换循环,如果有足够的图像,则一次将字段设置为一个。

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

If you need to open this up to allow more images in the future, you'll want to replace the Image1 and Image2 fields with a collection of images, and use your loop again to add each image in the uploaded files collection. 如果您需要打开它以在将来允许更多图像,则需要将Image1Image2字段替换为图像集合,然后再次使用循环将每个图像添加到上载的文件集合中。 Something like this: 像这样:

FileHandler fh = new FileHandler();

foreach (HttpPostedFileBase uploadedImage in Request.Files)
{
    Createsubcat4.Images.Add(fh.uploadedFileToByteArray(uploadedImage));
}

db.AddToSubProductCategory4(Createsubcat4);
db.SaveChanges();

EDIT: 编辑:

Now that you are saving the images correctly, you need to take a second look at your GetImage action. 现在您已正确保存了图像,您需要再次查看GetImage操作。 You'll notice that you correctly load both files into memory, however when you specify your action result ( return new FileStreamResult(stream,"image/jpg"); ) you are only ever returning the first stream. 您会注意到,您已将两个文件正确地加载到内存中,但是,当您指定操作结果( return new FileStreamResult(stream,"image/jpg"); )时,您只会返回第一个流。 You need a way to return the second stream when requested. 您需要一种在请求时返回第二个流的方法。 There are a couple ways to go about this, add another input parameter to specify which image to load or create a second action that only returns the second one. 有几种解决方法,添加另一个输入参数以指定要加载的图像或创建仅返回第二个图像的第二个操作。

To create the two action set up, your code would look something like this: 要创建两个动作设置,您的代码将如下所示:

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

These functions are almost identical and can easily be made 1 which takes a parameter to select which image to load. 这些功能几乎相同,可以很容易地设置为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");
}

This function would specify the imageNum as a query parameter like: 此函数会将imageNum指定为查询参数,例如:

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

I think your problem might be in this loop. 我认为您的问题可能在此循环中。

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

The Request.Files.Count > 0 should always be true since you are iterating through a list of Files. 由于要遍历文件列表,因此Request.Files.Count > 0应该始终为true。 However, the real issue is that with this loop you overwrite the properties of Createsubcat4 with each file, and then after the properties are set with the last file, that is what gets sent to the database. 但是,真正的问题是,通过此循环,您将用每个文件覆盖Createsubcat4的属性,然后在使用最后一个文件设置了属性之后,才将其发送到数据库。

If you are trying to add multiple records into the database (one for each image), you'll need to move the AddToSubProductCategory4 within the loop. 如果您尝试将多个记录添加到数据库中(每个图像一个),则需要在循环内移动AddToSubProductCategory4。 If you are trying to add two images to just that record, I'd recommend assigning each by name, and skipping the foreach loop. 如果您试图将两个图像添加到该记录中,建议您按名称分配每个图像,并跳过foreach循环。

 public JsonResult Update(ProductViewModel model, HttpPostedFileBase imgpath1, IEnumerable<HttpPostedFileBase> imgpath2)
    {
        if (imgpath1 != null)
        {
           foreach (HttpPostedFileBase postedFile in imgpath1)
            {
                //  var prodimage = Request.Files[i];
               
            }
          
        }


     
        if (imgpath2 != null)
        {
            foreach (HttpPostedFileBase postedFile in imgpath2)
            {
                 var prodimage = Request.Files[i];
               
            }

        }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM