load data into file upload MVC3 - asp.net-mvc-3

Html code:
#using (Html.BeginForm("Edit", "RoomInfo", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" class="multi" />
<p>
<input type="submit" value="Update" />
</p>
}
Controller code;
public ActionResult Search(string id)
{
var arrayid = id.Split(',');
int roomid = int.Parse(arrayid[0]);
ViewBag.ImageID = new SelectList(db.RoomImgs.Where(p => p.RoomID == roomid), "ImageID", "FilePath");
return View(roominformation);
}
I'm trying to upload the image into server and insert the file path into database and I successful to insert in to server and database, but now I need to select out the file path and put into the file upload tag in Edit mode. I trying some method but still fail to set in. How can I do it?

If what you're trying to do is display the previously uploaded image and then allow users to modify the image.
You can't populate the file input like you would a text box. What most websites do is display the image above the input and then have the input box below if you want to change the image. If you want to remove the image then you could also have a checkbox for removing the image. Then on the server side you have to check if the checkbox is checked and clear the image or, if the file input is populated store the new image and update the database.

Related

entity framework telling the context an entity has been updated

I have a scenario where I have an image property that is part of a product entity.
When allowing a user to Edit this product via MVC3 screen, the image property is displayed as follows:
<div class="editor-label">Image</div>
<div class="editor-field">
#if (Model.ProductItem.ImageData == null)
{
#:None
}
else
{
<img alt="Product Image" width="125" height="125"
src="#Url.Action("GetImage", "Product", new { Model.ProductItem.ProductId })" />
}
</div>
<div>Upload new image: <input type="file" name="Image" /></div>
To edit the current image the user essentially selects a new one via the upload. This means that the current ImageData property is null and the model state is invalid. The new image is past back in the post so I set this to the ImageData property and clear the model validation error.
I then save the 'changes' via the context.savechanges() method, however the context doesn't think there are any changes to this particular entity. To get round this I have done the following when on Edit:
if (context.Products.Local.Count() == 0)
{
Product procurr = context.Products
.Where(p => p.ProductId == product.ProductId)
.FirstOrDefault();
context.Entry(procurr).CurrentValues.SetValues(product);
}
Essentially I am forcing an update on the item in the list of products that I want to updqate (procurr is the item in the list and product is the new edited values I want to save)
My questions would be (A) Is this the best way to do this in terms of using the context, and (B) Is there a better way to do this in the UI ie someway of tying together the old and new image so as the model automatically picks up the changes?
Thanks
What you have done looks correct.
The basic idea is that when you get data from the server and return it to the browser, the EF context that you are using gets closed.
When the reply comes back from the browser you need to connect the data with the row that you are trying to update.
Reading the row based on the id, updating the relevant fields and then running save changes, is a good approach.

FileContentResult render in View without specific Controller Action

I have same action in a controller that fetch from db for example a Employee with a name, age, image (byte[]).
So I store the info in ViewBag. Then in the View the specific code for the image is:
<img src="#ViewBag.Image" alt="Logo" />
But when I see the content of the response I have:
<img src="System.something.FileContentResult" alt="Logo" />
I have seen a lot of examples that gets the FileContentResult from a specific Action in a Controller for example:
(The code is an example only)
public ActionResult GetEmployeeImage (int id){
byte[] byteArray = GetImageFromDB(id);
FileContentData file = new File (byteArray,"image/jpg");
return file;
}
And then render the image with:
<img src="#Url.Action("GetEmployeeImage", "Home", new { id = ViewBag.Id })" alt="Em" />
But I dont want that because I already have the image.
How can I render it to the View throw the ViewBag?
Thanks!
PD: Rendering image in a View is the same but was not concluded
One possibility is to use the data URI scheme. Bear in mind though that this will work only on browsers that support it. The idea is that you would embed the image data as base64 string into the src attribute of the img tag:
<img src="data:image/jpg;base64,#(Html.Raw(Convert.ToBase64String((byte[])ViewBag.Image)))" alt="" />
If on the other hand you want a solution that works in all browsers you will have to use a controller action to serve the image. So in the initial request fetch only the id, name and age properties of the employee and not the image. Then write a controller action that will take the employee id as parameter, query the database, fetch the corresponding image and return it as file result. Then inside the view point the src attribute of the img tag to this controller action.
Based on the answer of #darin , if any one wants to make it via calling a controller's action:
public FileContentResult GetFileByID(string ID)
{
try
{
// Get the object from the db
Ent ent = Biz.GetPatientsByID(ID);
// Convert the path to byte array (imagepath is something like: \\mysharedfolder\myimage.jpg
byte[] doc = EFile.ConvertToByteArray(ent.ImagePath);
string mimeType = File(doc, MimeMapping.GetMimeMapping(Path.GetFileName( ent.ImagePath))).ContentType;
Response.AppendHeader("Content-Disposition", "inline; filename=" + Path.GetFileName(ent.ImagePath));
return File(doc, mimeType);
}
catch (Exception ex)
{
throw ex;
}
}
In the front end:
<img id="ItemPreview" src="#Url.Action("GetFileByID","Patient", new {ID= Model.ID })" alt="" width="350" height="350" />
Where Patient is the controller name.

How to recieve all uploaded files in the controller in single post e.g. at once in a List<>?

I am having troubles uploading multiple files using Uploadify in MVC 3.
I select 3 files and post via ajax. I get the files in the controller but there is a problem.
Instead of getting the 3 files in one post, I see the controller gets hit 3 times for 3 files.
I want all 3 files available in the controller in a single post.
Is this possible?
[HttpPost]
public ActionResult UploadFiles()
{
//This always shows one file i debug mode
foreach (string fileName in Request.Files)
{
}
}
I want to process the file in one shot and save them in one shot.
Don't know for Uploadify but with a standard form if you want to upload multiple files at one you would use:
View:
#using (Html.BeginForm("YourAction","YourController",FormMethod.Post,new { enctype="multipart/form-data"})) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Message</legend>
//your html here
//as many input types you would like but they
//must have a same name attribute (files)
<input type="file" name="files"/>
</fieldset>
Controller:
[HttpPost]
public ActionResult YourAction(FormCollection values, IEnumerable<HttpPostedFileBase> files)
{
//do what you want with form values then for files
foreach (var file in files)
{
if (file.ContentLength > 0)
{
byte[] fileData = new byte[file.ContentLength];
file.InputStream.Read(fileData, 0, file.ContentLength);
//do what you want with fileData
}
}
}
So you would use IEnumerable<HttpPostedFileBase> files for multiple files, HttpPostedFileBase file for a single file and you would change the input in the view to
<input type="file" name="file"/>
Regards.

uploading PDF files and preview the uploaded files in ASP.net MVC3

i am a newbie in ASP.net MVC3 application.
I am working on this project where i have to work with PDF files.
I must be able to upload the PDF files to my file server and as soon as the file is uploaded the user must be able to see the preview of the uploaded document on the same page.
the Preview must be loaded in some DIV or partial view.
I have been spending a lot of time in research but still could not get what i need.
If anyone can help m with this i'll be very grateful.
public class FileUploadController[HttpPost]{
public ActionResult UploadFile(HttpPostedFileBase uploadFile){
//Save file to server
return new FileContentResult(fileContents, contentType);
}
}
#using (Html.BeginForm("UploadFile", "FileUpload", FormMethod.Post, new { enctype = "multipart/form-data" })){
<input type="file" name="uploadFile" id="uploadFile" />
<input type="submit" name="FileUpload" value="Upload" id="FileUpload"/>
}

File Uploading MVC3 and Microsoft Web Helpers

I am currently using the file upload helper that comes with Microsoft.WebHelpers like this
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
This correctly gives me a upload box but I am having two problems with this that I cannot seem to find an answer for.
The first problem is the box does not display the filename correctly if I have a long path.
The second problem is that I can add a bunch of new files but there does not seem to be a remove option that can be turned on.
I need to find a good tool to facilitate file uploads that will give me these options and seamlessly integrate with asp.net mvc3 or figure out a way to do this with the upload tool.
I am not sure what current tools are as far as nuGet packages go. However, I know that you can roll your own pretty easily.
In view:
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
<input type="file" id="files" name="files" size="60" /><input type="button">
...
<input type="submit">
}
<script>function(){ //make button add another input field with id="files"}
</script>
Note: new { enctype = "multipart/form-data" } is required to send files to the controller from a form.
In Action:
[HttpPost]
public ActionResult ActionName(IEnumerable<HttpPostedFileBase> files)
{
foreach(HttpPostedFileBase uploadFile in files)
{
//work with uploadFile
}
}

Resources