FileContentResult render in View without specific Controller Action - asp.net-mvc-3

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.

Related

Unable to read View Bag value from controller to view

I have created a view bag in controller's post back event which stores the image path.
Then,i used this view bag value in image src attribute.But image is not displayed.
Model:
public class FileManagement
{
public string FileName { get; set; }
public string Path { get; set; }
}
Code for uploading image
[HttpPost]
public ActionResult UploadPic(FileManagement fmanage, HttpPostedFileBase file)
{
string email = User.Identity.Name;
if (file != null && file.ContentLength > 0)
{
var FileName = string.Format("{0}.{1}", Guid.NewGuid(), Path.GetFileName(file.FileName));
var path = Path.Combine(Server.MapPath("~/Content/Uploads"), FileName);
file.SaveAs(path);
using (var session = DocumentStore.OpenSession("RavenMemberShip"))
{
var query = from q in Session.Query<Registration>() where q.Email == email select q;
if (query.Count() > 0)
{
foreach (var updated in query)
{
updated.FileName = FileName;
updated.Path = path;
session.SaveChanges();
}
}
}
}
else ModelState.AddModelError("", "Remove the errors and try again");
return View();
}
Controller
[HttpGet]
public ActionResult DisplayPic()
{
ViewBag.Imagepath = "C:\\Users\\Wasfa\\Documents\\Visual Studio 2012\\Projects\\MvcMembership\\MvcMembership\\App_Data\\Uploads\\annonymous.jpg";
return View();
}
[HttpPost]
public ActionResult DisplayPic(FileManagement fm)
{
using (var session = DocumentStore.OpenSession("RavenMemberShip"))
{
string ipath;
// string UserName = User.Identity.Name;
string UserName = "wasfa_anjum#yahoo.com";
var getPath = from p in Session.Query<Registration>()
where p.Email == UserName
select p;
if (getPath.Count() > 0)
{
foreach (var imgpath in getPath)
{
ipath = imgpath.Path;
ViewBag.Imagepath = ipath;
}
}
}
return View();
}
View:
#using (Html.BeginForm())
{
<div>
<img src="#Url.Content(ViewBag.Imagepath)" width="200" height="200" />
</div>
<input type="submit" value="Display" />
}
In my opinion, your problem is not to do with ASP.NET MVC, but you are missing some HTML/Web basics.
You have to understand that when you want to access a resource (html file, image etc), you have to use the HTTP URI syntax. You cannot and should not use your Windows file system path syntax.
Using something like C:\\Users\\Wasfa\\Documents\\Visual Studio 2012\\Projects\\MvcMembership\\MvcMembership\\App_Data\\Uploads\\annonymous.jpg" in HTML is completely wrong. To understand it better, imagine when you have your ASP.NET MVC website up and running for its users to access, they will come to you web page and the HTML downloaded on their browser will be:
<img src="C:\Users\Wasfa\Documents\Visual Studio 2012\Projects\MvcMembership\MvcMembership\App_Data\Uploads\annonymous.jpg" />
Do you think that path will exist on their computers? No.
So, to instruct the <img /> tag to fetch the image from the server, you have to specify either a full HTTP URI, for example:
<img src="http://mywebsite.com/Content/Uploads/annonymous.jpg" />
or a relative HTTP URI (which is like a relative path from your web site's root folder):
<img src="~/Content/Uploads/annonymous.jpg" />
Another problem with your approach is that App_Data is a special folder and its contents are not accessible from the browser by default. So, as per ASP.NET MVC convention, you can create a Content folder in your project to hold your static images and other static content like style sheels, and then link to them.
Once you do that, no one stops you from providing the relative path for your default image as a ViewBag property.
ViewBag.Imagepath = "~/Content/Uploads/annonymous.jpg";
And then use it the way you want:
<img src="#Url.Content(ViewBag.Imagepath)" width="200" height="200" />
I also expect the paths you subsequently fetch from the database, also follow this scheme.
path for image must have forward slash (/),
more over this type of path might work only in your local system and not in your server.
Try using Server.MapPath to fetch your path
Using ViewBag for displaying image is a bad idea, consider using your model property to store the image path and use
<img src="#Url.Content(Model.ImagePath)" alt = "Image" />
EDIT :
Controller:
[HttpGet]
public ActionResult DisplayPic()
{
FileManagement fm = new FileManagement();
fm.Path = "Your image path";
return View(fm);
}
View :
`<img src="#Url.Content(Model.path)" alt = "Image" />`
didn't check the code, but this should work.
It looks like you only really need one result for getPath, this might clean your code up a bit
var imgPath= Session.Query<Registration>()
.FirstOrDefault(p => p.Email == UserName)
.Select(i => i.Path);
if (!string.IsNullOrEmpty(imgPath)
ViewBag.Imagepath = imgPath;
else
{
//no user found, handle error
}
Other than that your code looks fine, can you debug through your application and see what imgPath is equal to after your query is run?
In case, if the image to be displayed when export to excel from the web page.
Use the server path of the image, otherwise, the image would not be loaded from the assembly image folder.
Example:
config:
<add key="LogoPath" value="http:\\mysite\\images\\" />
code:
companyLogo = string.Format("{0}myLogo.png", System.Web.Configuration.WebConfigurationManager.AppSettings["LogoPath"]);
HTML:
<img src='" + #Url.Content(companyLogo) + "' />

Toggle between Images asp.net MVC3

I have a place holder for a profile photo.I want it to get profile image from database (this works OK)<img src="#Url.Action("Thumbnail", "Photo", new { id = Model.Mebrief.myGuid, size = "small" })" alt="#Model.UserName" width="150" height="150"/>.
Problem:
If there is no profile image ,it should get default place holder image located here:
<img src="#Url.Content("~/Content/profile-template/img/friend_avatar_default.jpg")" alt="crazy" width="150" height="150"/>
All these are supposed to show in a div below:
<div id="profile"> </div>
NOTE: I am using .cshtml razer page.
You could try something like this in your controller.
public ActionResult Photo(int photoId)
{
MyPhoto photo = null;
try
{
MyPhoto = db.GetMyPhotoById(photoId);
return new FileStreamResult(new MemoryStream(photo.Image), photo.ImageMimeType);
}
catch (Exception ex)
{
//use the default image
return new FilePathResult(Url.Content("~/Content/profile-template/img/friend_avatar_default.jpg"), "image/jpg");
}
}
It would be helpful to see what you are doing in your controller, but I'm guessing you are returning a FileStreamResult from the bytes you get back from the database.
Hope this helps.
below is not a valid razor syntax but just an idea - Use ternary operator
if true ? new image : default image
Model != null
?
img src="#Url.Action("Thumbnail", "Photo", new { id = Model.Mebrief.myGuid, size = "small" })" alt="#Model.UserName" width="150" height="150"/>"
:
img src="#Url.Content("~/Content/profile-template/img/friend_avatar_default.jpg")" alt="crazy" width="150" height="150"/>

Rendering image in a View

I'm trying to show some picture for user in a strongly typed View..
In Model members there is one that represents contents of image (ex. jpeg)
How should I pass this content to img tag to render this image?
model looks like:
publiс class Image {
public virtual FileContentResult currentImage { get; set; }
public Image()
{
currentImage = createSomeImage();
// createSomeImage returns new FileContentResult(bmpBytes, "image/png");
}
}
View looks like
#model app.Models.Image
<img src='#Model.currentImage' alt="" class="img" />
and I render it from parent View as:
#Html.Partial("_ImageShow", new app.Models.Image())
I've searched a lot, but found only implementations of returning image as a result of action of some controller..Is there any way to show image having fileContentResult in a View?
Thanks in advance.

Mvc 3 Image Upload Gallery

I have implemented a file upload for images using ASP.NET Mvc 3 and the Microsoft.Web.Helpers NuGet package. The implementation is quit simple as it allows you to browse for a file and upload it to a specified directory.
Here is what I have for my image upload solution using ASP.NET MVC 3 and the Microsoft.Web.Helpers NuGet plugin.
Now the ViewModel code
namespace MvcImageUpload.Models {
public class ImageUploadViewModel {
[UIHint("UploadedImage")]
public string ImageUrl { get; set; }
public string ImageAltText { get; set; }
}
}
Now for the controller I've simply dropped this into the Home controller, since this is just a mock project to get it working. I just added an ActionResult which takes an ImageUploadViewModel as a parameter.
public ActionResult Upload(ImageUploadViewModel model) {
var image = WebImage.GetImageFromRequest();
if (image != null) {
if (image.Width > 500) {
image.Resize(500, ((500 * image.Height) / image.Width));
}
var filename = Path.GetFileName(image.FileName);
image.Save(Path.Combine("../Uploads/Images", filename));
filename = Path.Combine("~/Uploads/Images", filename);
model.ImageUrl = Url.Content(filename);
model.ImageAltText = image.FileName.Substring(0, image.FileName.Length - 4);
}
return View("Index", model);
}
My view for the uploading of images is simple, it has an Html.BeginForm, which handles the Post form method and has the encoding type set to be "multipart/form-data".
Then using The Microsoft.Web.Helpers.FileUpload helper, I request an image from the HTTP post and then display it using a custom DisplayFor template, called ImageViewer.
#model MvcImageUpload.Models.ImageUploadViewModel
#using Microsoft.Web.Helpers;
#{
ViewBag.Title = "Index";
}
<h2>Image Uploader</h2>
#using (Html.BeginForm("Upload", "Home", FormMethod.Post,
new { #encType = "multipart/form-data" })) {
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: false,
includeFormTag: false, addText: "Add Files", uploadText: "Upload File") <br />
<input type="submit" name="submit"
value="Upload Image" text="Upload Images"
style="font-size: .9em;" />
#Html.DisplayFor(x => x, "ImageViewer")<br />
}
Here is what the custom DisplayTemplate looks like
#model MvcImageUpload.Models.ImageUploadViewModel
#if (Model != null) {
<h4 style="color:Green;">Upload Success!</h4>
<p>
Alt Text has been set to <strong>#Model.ImageAltText</strong>
</p>
<img style="padding: 20px;"
src="#(String.IsNullOrEmpty(Model.ImageUrl) ? "" : Model.ImageUrl)"
id="uploadedImage" alt="#Model.ImageAltText"/>
}
This all works and the image gets successfully uploaded to the /Uploads/Images/FileName.extension on the form post.
My question
How can I now have another view to display all the images in that directory, paged and be able to select and delete and image, from the view and the directory?
Also I know the Microsoft.Web.Helpers.FileUpload, supports uploading of multiple files, but I can't find how to implement this with my current solution. Any help would be greatly appriceated.
After you click the Upload Image button, the system should call method which uses Request to get the file.
[HttpPost]
public ActionResult Upload()
{
if(Request.Files != null && Request.Files.Count > 0)
{
for (int i = 0; i < request.Files.Count; i++)
{
var postFile = request.Files[i];
if (postFile != null && postFile.ContentLength > 0)
{
if (postFile.ContentLength < GetMaxRequestLength()) //10MB
{
var file = new ContractAttachment
{
Name = Path.GetFileName(postFile.FileName),
ContentType = postFile.ContentType,
FileLength = postFile.ContentLength,
FileData = GetStreamBuffer(postFile)
};
files.Add(file);
}
}
}
}
}
Hope this help.
what you are asking about looks rather implementation to me then any query....
to Display:
Fetch all images from your Uploads/Images directory through DirectoryInfo... you can search a directory based on some extension and then it will give you a result set which you can iterate.....
Create a view that will display all records as Image links and in controller fetch the resultset to that View.... Bind those records as you want them to display in your VIEW...
System.IO.DirectoryInfo info = new System.IO.DirectoryInfo("your directory path");
var filesinfo= info.GetFiles("*.jpg", System.IO.SearchOption.AllDirectories);
var filenum= filesinfo.GetEnumerator();
while (filenum.MoveNext())
{
//populate some entity like in your case you have ImageUploadViewModel
}
and you can implement you delete logic using Ajax or through post back depends how you want it....
Asp.net MVC Views following this tutorial and it will let you go through this....
but again what you are asking is more like implementation Code not any issue....
The approach I've followed previously, is to persist the file information in a database(or whatever is appropriate). e.g. path, filename, content-type, filesize.
This gives you the most flexibility when editing (alt text, title, description, relation to other objects).
Downloading/Viewing the files can then be handled based on path convention, by creating a ViewImage controller which just gets an image id as parameter.
You can then build a url from the path to the file and you only need to set the content-type.
IIS then does the rest.

How to load an image from ASP.NET MVC controller in a Facebook canvas app?

In my Facebook canvas application, I want to load an image from my ASP.NET MVC Controller.
So I do somethinhg like this, in my controller (simplified):
public ActionResult GetImage(int id)
{
// ....
return File(#"c:\temp\1.jpg", "image/jpeg");
}
And it's called from my aspx page like so:
<img src="/Home/GetImage?id=20" alt="Test"/>
But the image is not displayed, I get a "red x".
So I fire up Fiddler and see that the request does indeed return the image, but the data is prepadded with Facebook's frame html:
<html><head><script type="text/javascript">
top.location = "http://www.facebook.com/dialog/oauth/?state=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&client_id=xxxxxxxxxxxxxxx&redirect_uri=http://localhost:5000/facebookredirect.axd";
</script></head><body></body></html>?????JFIF??H?H????
?ICC_PROFILE???
????????mntrRGB XYZ ?????$?acsp???????????????????????????????????
Which of course is not vaild jpeg image data.
How can I avoid this pre padded data?
Never mind, I found out myself that the signed_request data was (yet again) missing.
I thought the only way to pass this was thru a HTTP header, but (like magic) I could pass it as a parameter as well causing the request to be validated.
<img src="/Home/GetImage?id=20&signed_request=<%=Request.Params["signed_request"] %>" />
public ActionResult GetImage(int id), string signed_request)
{
var auth = new CanvasAuthorizer();
if (auth.Authorize())
{
// Indeed, I'm now authorized
return File(#"c:\temp\1.jpg", "image/jpeg");
}
/// ...
}
/M

Resources