невозможно загрузить несколько изображений БД с помощью asp.net mvc - PullRequest
2 голосов
/ 19 апреля 2011

Я пытаюсь загрузить несколько изображений в БД на SQL Server 2008R2.Я использую ASP.NET MVC 3 в C #.Происходит то, что я получаю отображаемые изображения, но проблема в том, что второе изображение отображается как дважды.Так что это дубликат.Я не уверен, почему первое изображение не отображается.

Моя таблица 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");

    }

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 ]

4 голосов
/ 27 апреля 2011

Код, который указан в списке, циклически перебирает файлы, и для каждого из них значение 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();

EDIT:

Теперь, когда вы правильно сохраняете изображения, вам нужно еще раз взглянуть на действие 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}

0 голосов
/ 27 апреля 2011

Я думаю, что ваша проблема может быть в этом цикле.

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...