2012-02-21 2 views
1

Я использую MVC 3 и используя плагин AjaxUpload для загрузки изображения с использованием AJAX. Я не хочу сохранять изображение в файловой системе, а не сохранять его в объект сеанса, а затем выводить поток, чтобы заполнить элемент управления изображением в форме? Кто-нибудь знает, как это сделать?ASP.NET MVC 3 Preview Image

ответ

1

SomeView.cshtml:

<img src="@Url.Action("/Image/Render")" /> 

ImageController.cs:

public ActionResult Render() { 
    return File((byte[])Session["Avatar"], "image/jpeg") 
} 
4

Никакая идея, почему бы никогда не хотят, чтобы сделать это (сохранить файл в сессии), потому что если у вас есть много пользователей загрузки их файлы одновременно, сохраняя эти файлы в памяти вашего веб-сервера, особенно если эти файлы большие, не заставит этот сервер работать очень долго. Рекомендуется сохранить файл в файловой системе.

Но в любом случае, вот как вы можете это сделать (если вы не читали или заботился о своем предыдущем замечании):

[HttpPost] 
public ActionResult Upload(MyViewModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(model); 
    } 

    var buffer = new byte[model.File.InputStream]; 
    model.File.InputStream.Read(buffer, 0, buffer.Length); 
    Session["uploadedFile"] = buffer; 
    return View(model); 
} 

, где свойство файла на моделях просмотра является HttpPostedFileBase. Затем вы могли бы иметь действие контроллера, который будет служить этот файл:

public ActionResult Image() 
{ 
    byte[] buffer = (byte[])Session["uploadedFile"]; 
    return File(buffer, "image/png"); 
} 

и с точки зрения вы будете иметь <img> тег, указывающий на это действие:

<img src="@Url.Action("image")" alt="" /> 

Теперь, конечно, AjaxUpload plugin позволяет загрузите файл с помощью AJAX, поэтому вам не нужно перезагружать всю страницу. Таким образом, в этом случае действие вашего контроллера может просто вернуть объект JSON, чтобы указать, удалось ли процесс загрузки, а затем в обратном вызове успеха установить свойство src тега <img> на действие контроллера, которое будет обслуживать файл.

+0

Благодарим за это. Я вижу, что вы имеете в виду в сеансе. Если пользователь загружает изображение только для предварительного просмотра (так что вы можете загрузить другое изображение в любое время, чтобы отменить тот, который у них есть в настоящее время) предложили бы вы сохранить его в файловой системе или базе данных? – Paul

+0

жаль поднимать мертвую нить, но как я могу поместить хранение изображения в файловую систему? Я видел много потоков об этом здесь, в SO, но ничего, что объясняет, как это сделать. должен ли я создать другой подобъект для этого (или веб-сайта)? если да, то как мне получить доступ к этому с моего исходного сервера сайта? как они сказали, что у него не должно быть доступа к основным файлам или что-то в этом роде? – gdubs

1

Некоторые примеры кода. Измените его так, как вы хотите. Не очень хорошая идея переместить изображение в сеанс, если много пользователей. Лучше вставить его в db, если он недолговечен или долговечен, более постоянное хранилище (возможно, файловая система).

public ActionResult UploadImage() 
    { 
     foreach (string imageName in Request.Files) 
     { 
      HttpPostedFileBase file = Request.Files[imageName]; 
      if (file.ContentLength > 0) 
      { 
       BinaryReader br = new BinaryReader(file.InputStream); 
       byte[] content = br.ReadBytes(file.ContentLength); 
       Session[imageName] = content; // better to store in a db here 
      } 
     } 
     return View(); 
    } 

    // return the image (controller action) /mycontroller/ViewImage?imageName=whatever 
    public FileStreamResult ViewImage(string imageName) 
    { 
     byte[] content = (byte[])Session[imageName] ; // where ever your content is stored (ideally something other than session) 
     MemoryStream ms = new MemoryStream(content); 
     return new FileStreamResult(ms, "application/octet-stream"); // set content type based on input image, it might be png, jpg, gif etc., 
    } 

Надеюсь, это поможет.