Rotativa / Wkhtmltopdf images not displaying - asp.net-mvc

I am currently creating an MVC 4 web application.
I have an action that has a base background image which is always the same then an arrow image which changes in degrees depending on the information that is collected within the action.
I call this action using
<img src="#Url.Action("trend-image", "NonReg_Reports")" alt="background" width="245" height="105" />
This works fine when it is called and is just displaying a HTML webpage. It gives me the HTML.
<img src="/nonreg-report/01495344/trend-image" alt="background" width="245" height="105">
I am then using Rotativa / Wkhtmltopdf to convert this HTML page into a PDF. This runs the same piece of code as above.
The problem is I am just getting a white box with the alternative text in it if I use the code above.
If I use <img src="~/Content/images/trend_back_medium.png" alt="astuff" /> which is the actual background image in my project it works fine.
The image from the code above can not be saved anywhere due to how it is used. I am thinking that it is a path problem, but after trying lots of different things I can still not get it to work.
Any suggestions or help would be greatly appreciated Thank you.

I had the same problem. Normal html view was ok with pictures, pdf was not display it. I used Server.MapPath to point to picture and it was ok...
<img src="#Server.MapPath("~/Folder/SubFolder/Subfolder/ImageName.png")" />
I hope this will help
Adam

I faced the same problem and I found a workaround, not a nice one, but it suits my needs.
It seems that Rotativa(Wkhtmltopdf?) have a problem with images which are returned from http handler (at least my case). So to handle this situation, in controller action before return new ViewAsPdf... my code manually save file to some local 'temp' folder and replace 'src' of images in rendered view with paths to that local files in server path manner, eg: http://localhost/img/temp/trend-image.png.
This is not a nice solution, if you already found better one, let me know.

Adding the attribute [System.Web.Mvc.AllowAnonymous] to the controller method returning the image solved the problem for me.

It seems to work okay via css...
I was trying to display a logo at the top of the page and switched it with a div and set the height and width to that of the image.
CSS:
div.logo {
background-image: url("/images/logo/logo.png");
height: 53px;
width: 185px;
}
HTML:
<div class="logo"></div>

I found that with my pages, the images were not showing because they were .gif files.
Rotativa can have problems with gifs.
When I changed the images to .jpg or .png everything worked well.

I think it might come down to basically the ".png" bit being missing.
You could add a mapping like this /nonreg-report/01495344/trend-image.png ยป /nonreg-report/01495344/trend-image and have both of the urls active, why not? That way wkhtmltopdf is fooled and you still have your dynamic image without saving it anywhere on disk. Dynamic urls can work, I do that for live-converting gif2png for wkhtmltopdf.
Also it might help to have an absolute url, which I think you can do with something like this:
src="#Url.Action("trend-image", "NonReg_Reports", null, Request.Url.Scheme)"

If you are specifiying height and width then make sure you should write it in style tag
like <some-tag style="height: 100px; width:100px">

Related

Can't access the image through data-image property

I am facing trouble with this div element during loading the image. 404(Not Found)
<div class="sidebar" data-color="purple" data-background-color="white" data-image="../assets/img/sidebar-1.jpg"></div>
Here is my code in Views. I am not familiar with this data-image tag. I have kept "sidebar-1.jpg" image inside my app/assets/images folder.
Now how can I solve this error and get the image works without harming other attributes(data-color, data-background) of this div element?
Plz help me
The path should be /assets/sidebar-1.jpg
Hope it work.

Isn't ASP.NET MVC _layout.cshtml similar to Webforms Master page?

I have an MVC 4 project with a layout page that I have setup with images that are links like this
<img id="logoImage" src="~/Content/siteImages/myLogo.png" alt="My logo" title="Welcome to my site" />
I have also tried this:
<img id="logoImage" src="../Content/siteImages/myLogo.png" alt="My logo" title="Welcome to my site" />
And this:
<img id="logoImage" src="#Url.Content("~/Content/siteImages/myLogo.png")" alt="My logo" title="Welcome to my site" />
These all work fine as long as the controller is the home controller. I use an Actionlink #Html.ActionLink("Northwind Demo", "Northwind", "Northwind", null, new { #class="links"}) to get to another controller.
As soon as the ActionLink is clicked, my images disappear. I examined the rendered link text in the browser and it is the same as it was before.
src="Content/siteImages/myLogo.png"
However, when examining the request in the network tab of the browser the url for the image is now
Northwind/Content/siteImages/myLogo.png
which does not resolve. For some reason the browser is adding the name of the controller to the beginning of the request for the image. I am sure that I am missing something really dumb but...
How do I fix this?
Edit
I wonder if this is an issue that only happens when running locally and may disappear when deployed to a server? I am still unable to fix this.
Edit
I am really struggling with the fact that no one else has encountered this before. I was under the impression that _layout.cshtml was like a master page in WebFroms. I need some suggestions here.
EDIT
So I had a moment of success. I changed the name of the entry method into the Northwind controller to Index and the images displayed properly in the index view. However, if I call another view, then the images disappear again.
I use radion buttons to select a different view based on which one is selected like this:
public ActionResult Search()
{
int id = Convert.ToInt32(Request.Form["radio"]);
switch (id)
{
case 1:
return View("Customer");
case 2:
return View("Orders");
case 3:
return View("Employees");
default:
ViewBag.Error = "Search parameter not found";
return View("Index");
}
}
I am still not able to fix this but I think that I am closer to a solution with someone's help.
Thanks in advance
Don't use relative addressing in MVC, since as you can tell you run into problems because views can be accessed from multiple routes (ie, /, /Home, /Home/Index, etc.. are all the same view, but different paths, if you use ../whatever then /Home/Index becomes /Home/whatever, / and /Home become /whatever)
Always use either #Url.Content to generate urls if you're not in a Razor 2+ view. If you're in Razor 2 or greater, then you can use src="~/Content/images/whatever"
If these methods are not working, then you need to look at your Application root, web.config, etc.. because MVC is becoming confused about where the root of the site is.
Well I have figured this out and I feel like an idiot! I have a script file that I use to change the images when it becomes small enough so that they continue to fit on the screen as it gets smaller for a responsive design. Like this:
$("#logoImage").attr("src", "Content/siteImages/logoSmall.png");
Well, the missing / at the very beginning is what was causing the issue. Adding the / fixed all my issues. Like this:
$("#logoImage").attr("src", "/Content/siteImages/logoSmall.png");
Even though I feel very silly at this moment, I am posting my answer in case someone else comes along and has a similar issue. Don't forget your script files and don't leave anything out when trying to fix a weird issue. Thanks to everyone that looked at this and tried to help.

dynamically load image names from database and display them using jsf 2.0

i'm trying to find a solution to load image names from a database and display them on a webpage.
Basically, when i display an image i do it like this:
<h:graphicImage value="#{resource['mywebapp:image.png']}">
</h:graphicImage>
So now instead of image.png i would like to dynamically load alternative images. Problem is, that i can't use an EL nested expression inside another one (at least i have not found out how). To put the logic into the backing bean also does not help in this case, because then it is rendered like that:
<img src="#{resource['mywebapp:somedynamicallyloadedimagename.png']}">
</img>
The only thing that works, is to directly generate the path in the backing bean:
public String getImage() {
this.image = "/mywebapp/javax.faces.resource/"+this.image+".jsf?ln=images";
return image;
}
However this "solution" is far from elegant, since everything is hardcoded and this is nothing i'm going to put in a production app.
What would be a good solution to do this? I would like to avoid putting the images into the database and using primefaces..
Since i'm not an experienced JSF coder (as you can probably tell), i would highly appreciate some thoughts on this topic...thanks in advance!
Try
<h:graphicImage library="images" name="#{generated.name}" />

How to Cache image when src is some action which returns image?

There are lots of questions about how to force the browser to cache or not to cache any image. But, I am facing slightly different situation. In several places of my web page, I am using following code for the images.
<img title="<%= Html.Encode(Model.title)%>"
src="<%= Url.Action(MVC.FrontEnd.Actions.RetrieveImage(Model.SystemId))%>"/>
So, in the generated HTML it is like
<img title="blahblah" src="http://xyz.com/FrontEnd/Actions/RetrieveImage?imageId=X">
Where X is some integer. I have seen that though the browser (IE or Mozilla) caches images by default, it is not caching images generated by above method.
Is there any way I can tell browser to cache images of above type?
Thanks in advance.
In order to do this you can set the Expires and MaxAge headers of the response. To simplify things, you can create a custom ActionFilter.
Here's a good guide in how to achieve this: ASP.NET MVC Action Filter - Caching and Compression

How do change img src.value for upload new image

this code isnt work
anyone know how ?
I would suggest using http://jquery.com/ as it provides many function to do things like this, but using CSS style selectors instead of the nasty javascript dom.

Resources