can we render image sitecore mvc view using itemID - asp.net-mvc

In my MVC view i'm able to get Image ItemID now want to render it
i'm doing this as:
// Getting ImageItemID
ID myImageItemId = new ID(image.Substring(image.IndexOf('{', 0), 38));
// Getting ImageItem according myImageItemId
Item myImageItem = db.GetItem(myImageItemId);
#Html.Raw(myImageItem)
<img src="#myImageItem"/>
please someone can hep to what mistake i'm doing here

You need a dedicated action that will return the contents of the actual image by it's id:
public ActionResult Image(int imageID)
{
byte[] image = SomeService.GetImageBytes(imageID);
return File(image, "image/jpeg");
}
After that you can use this action in your view:
<img src="#Url.Action("Image", "SomeController", new {imageID = myImageItem})"/>

Related

Get both image and tooltip in one call

How can I get both the image and tooltip in a single call to a MVC controller method? I can use something like the following to get the image, but how to also get the associated tooltip? The use case is to display an image if the user is allowed to see the image, else display a generic image and a tooltip indicating why the image is not being shown.
To clarify, I would like to avoid two calls to the controller, once to get the image path and tooltip, and another to get the image file. Not only will this result in two round trips across the network, it would also repeat the validation checks. The problem is that the img src call only accommodates the image, not other properties such as the title associated with the image.
<img src="#Url.Action("GetPicture", "User", new { userId = Model.User.Id })" />
Can't you just have a second method for GetTitle using the same permission logic from GetImage and return the appropriate text for each user? Then call this method for the title attribute.
Can you approach the problem in the following way.
Create Model
public class ImageViewModel
{
public string ImagePath
{
get;
set;
}
public string ImageTitle
{
get;
set;
}
}
Create a partial View
#using StackOverFlowProject.Models
#model ImageViewModel
<img src=#Model.ImagePath title=#Model.ImageTitle />
Your Controller
public PartialViewResult _Image(string userID)
{
ImageViewModel model = new ImageViewModel();
//Here You can check what image and tooltip you want show to the user
//model = //FillData from DB /
return PartialView("_Image", model);
}
and at last in Your MainView where you want to display the Image render the partial view
Not sure if this is the best way to do it, but I did it by creating an Ajax form, submitting it using jQuery, returning a JSON object with the byte array encoded as a Base64 string, and using Javascript to display the image. Seems to be working so far, will know more from further tests.
In the view:
<div id="imgDiv">
#using (Ajax.BeginForm("GetImg", "User", null, new AjaxOptions()
{
HttpMethod = "POST",
Url = Url.Action("GetImg", "User"),
OnSuccess = "DisplayImageWithTooltip(data, 'imgDiv')",
}, new { id = "ImgForm", #class = "imageGetterWithTooltip" }))
{
#Html.AntiForgeryToken()
#Html.Hidden("userId", #Model.User.Id)
}
</div>
Javascript to submit form:
$(".imageGetterWithTooltip").submit();
In Controller (based on https://stackoverflow.com/a/9464137/1385857)
return Json(new
{
fileBytes = Convert.ToBase64String(<File byte[]>),
fileType = <FileType>,
tooltip = <toolTip>
}, JsonRequestBehavior.AllowGet);
Javascript to display image
function DisplayImageWithTooltip(data, target) {
var oImg = document.createElement("img");
oImg.width = 150;
oImg.height = 150;
oImg.setAttribute('src', "data:" + data.fileType + ";base64," + data.fileBytes);
oImg.setAttribute('title', data.tooltip);
document.getElementById(target).appendChild(oImg);
}
Using Manish's ideas, my simplified solution is to create a partial view and supply it the image data directly:
Controller:
vmMiniData data = new Models.vmMiniData();
byte[] byteArray = Users.GetPersonnelImage(personnelID);
if (byteArray != null)
{
data.ImageStr = Convert.ToBase64String(byteArray);
}
else
{
data.ImageStr = Convert.ToBase64String(Users.GetPersonnelImage("00000000-0000-0000-0000-000000000000")); //get blank image
}
data.CaptionStr = Users.GetUserJobTitle(personnelID);
return PartialView("Personnel/MiniPersonnelPartial", data);
Model:
public static byte[] GetPersonnelImage(string personnelID)
{
byte[] img = (byte[])(from record in db.PersonnelImages
.Where(R => R.PersonnelID == new Guid(personnelID))
select record.Image).FirstOrDefault();
return img;
}
Then in the partial:
#model vmMiniData
<div>
<div>#Model.CaptionStr</div>
<div> <img src="data:image;base64,#Model.ImageStr" style="width:60px;min-height:30px;" /></div>
</div>
It works very well in MVC 5 :).

Controller returned data not binding to image in asp.net MVC

I want to get image from database and display it in the view. image is retrieved but from database but not binding to image. This is my controller code
public ActionResult GetSignatureDetails()
{
byte[] image = (from m in objIycEntity.Signatures
where m.SignatureID == 5
select m.Signature1).FirstOrDefault();
var stream = new MemoryStream(image.ToArray());
return new FileContentResult(image, "image/jpeg");
}
And this is my view
<img src='#Url.Action("GetSignatureDetails","Agent")' />
But always image src in firebug is src="/Agent/GetSignatureDetails"
Please can any one help me what I am doing wrong
I give you a sample code hope this will help you:
View :
#model MvcApplication2.Models.AgentProfile
#{
ViewBag.Title = "imageDemo";
}
<h2>imageDemo</h2>
<img width="100" height="80" src="/Profile/ShowImage/2" alt="" />
And Controller Code Like this:
public ActionResult ShowImage(int id)
{
if (id>0)
{
AgentProfile objag = new AgentProfile();
MvcApplication2.Models.Image obj = new MvcApplication2.Models.Image();
obj.ImageID = id;
DataSet ds = obj.SelectImage();
objag.ImageSource = (byte[])ds.Tables[0].Rows[0]["ImageContent"];
//objag.ImageSource = (byte[])row["ImageContent"];
return File(objag.ImageSource, "image/jpg");
}
else
{
return RedirectToAction("Index");
}
}
Thanks.
have you tried it this way?
public FileContentResult GetSignatureDetails()
{
byte[] image = (from m in objIycEntity.Signatures
where m.SignatureID == 5
select m.Signature1).FirstOrDefault();
return File(image, "image/jpeg");
}

mvc4 canot call a function in a controller

i have a view to display the information of a specific model.
in that information i have an image, which is a byte of array.
now i want to display that image.
i make this in my view
<img src="#Url.Action("getImg", "Image", new { image = Model.image })" />
note that the Image controller is not the same controller that the current view belong to
what am i getting wrong please?
all the other imformation are displayed correctly.
Edit
this is the controller that i want to call
public class ImageController : Controller
{
//
// GET: /Image/
public ActionResult Index()
{
return HttpNotFound();
}
// To convert the Byte Array to the image
public FileContentResult getImg(byte[] image)
{
if (image != null)
{
return new FileContentResult(image, "image/jpeg");
}
else
{
return null;
}
}
}
This appears to be a very poor choice in design. This code:
<img src="#Url.Action("getImg", "Image", new { image = Model.image })" />
So the image will be sent as a byte array to the client (lets say 60,000 bytes). Will create html that might look like:
<img src="/Image/getImg/?image=bc15b2c53... (lots of characters" />
This html is really long, basically sending the image as a byte array to the client. Next the browser will make another request to get the image by sending the byte array back to the controller (another 60,000 bytes to the server).
Next, the controller will return the byte array sent to it back again to the browser, as an image. Three trips of 60k of data is a terrible idea.
Update
The better way to do this is to not send the bytes array to the view, but an ID.
<img src="#Url.Action("getImg", "Image", new { id = Model.id })" />
Then in the controller:
public class ImageController : Controller
{
public FileContentResult getImg(int?/guid? id)
{
if (id.HasValue)
{
byte[] bytes = db.GetBytesById(id.Value);
return new FileContentResult(bytes, "image/jpeg");
}
else
{
// be nice to the browser, send the correct result!
return new FileNotFoundResult();
}
}
}

Passing an url as parameter to controller action

On my asp.net mvc page I need to render multiple images that are stored on third-party images hosting service. The service has some api which returns me a list of image urls.
In *.cshtml file a have the fallowing html markup:
#foreach (var img in Model.Images)
{
<img src="#img.ImageUrl" />
}
It's works perfectly. But for some reason I can't use direct URL to the image in the "src" attribute. Next, I have created new async controller that should return an image:
public class ImagesController : AsyncController
{
//
// GET: /Images/
public void GetImageAsync(string url)
{
AsyncManager.OutstandingOperations.Increment();
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
AsyncManager.Parameters["response"] = response;
AsyncManager.OutstandingOperations.Decrement();
}
public FileResult GetImageCompleted(WebResponse response)
{
return base.File(response.GetResponseStream(), response.ContentType);
}
}
Now I need to pass a full image url to my controller action.
Something like this:
#foreach (var img in Model.Images)
{
<img src="Images/GetImage/**#img.ImageUrl**" />
}
how to create a new route for passing this parameter to action?
Thanks!
You mean this?
routes.MapRoute(
"GetImage",
"Images/GetImage/{*url}",
new { controller = "Images", action = "GetImageAsync" }
);
I'm not sure why you need all that though. An AsyncController + routing in order to fetch all image url's seems to be overkill...

ASP.NET MVC Form Submission

I'm having a bit of a brain fart; it must be Monday...
I have an MVC form, which allow the user to submit an image.
The image is saved to a folder, then I want to redirect to another Controller and Action to display the image.
What are my options for passing the image name and path back to the controller action to display the graphic?
// Handles the updload, contains a control (ascx)
// and the control's action method is in another controller
public ActionResult Index()
{
return View();
}
// I want this page to display the image uploaded in the Upload.ascx control
// that is in the index method above:
public ActionResult Result()
{
ViewData["MyImage"] = ???
}
Thanks much.
Where is the image being stored? In your content area or in a database? If it's in a database, then I'd construct the controller/action url to display that image form the db. If it's in your content area, then you can construct the url based on the name of the uploaded file. I'd probably create a model rather than passing the url in view data, but view data is a valid (i.e., it works) alternative.
public ActionResult Result( int id ) // db storage
{
return View( new UploadModel
{
ImageUrl = Url.Action( "display", "image", new { id = id }
} );
}
public ActionResult Result() // content area
{
var imageName = ... get image name from ??? ...
return View( new UploadModel
{
ImageUrl = Url.Content( "~/content/images/uploads/" + iamgeName );
});
}

Resources