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

时间:2011-04-19 12:21:54

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

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

我的SubProductCategory4表格包含以下列(为简单起见)......

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

我的控制器具有以下创建方法代码...

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

    }

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

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

2 个答案:

答案 0 :(得分:4)

列出的代码循环遍历文件,对于每个文件,将Image1Image2设置为相同的内容。当您上传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);

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

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}

答案 1 :(得分:0)

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

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 > 0应该始终为真。但是,真正的问题是,使用此循环,您将使用每个文件覆盖Createsubcat4的属性,然后在使用最后一个文件设置属性后,即将其发送到数据库。

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