ASP.NET rdlc with external images not displaying images in PDF - asp.net

I'm using the Microsoft ReportViewer that comes with ASP.NET and have a report parameter that should be setting the value (path) of an image in my report. I'm providing the path as a complete URL right now, starting with http:// but have also tried this as an app relative path, site rooted path, etc. and for some reason the image is always showing as the red X when it exports to PDF. I'm just creating an instance of a control in code, setting the properties and exporting directly to the response stream so it acts a download.
I'm just not sure what the problem could be with the image not showing up, so if anyone has any ideas please let me know.
UPDATE 1
I've determined that I can embed the image with a URL if it is on my public web server but when I'm running in localhost the image won't embed. I have confirmed for localhost that if I paste the same URL into my browser the image will open fine. As far as I know, I don't have a proxy. So I can work around my issue, but I still don't understand what the problem is with localhost.
UPDATE 2
Forgot to mention that when the URL to the image is opened from a browser it works fine.

It is not possible for a PDF to contain a reference an external image (at least from my understanding). In order for an image to appear in the PDF, it must be embedded into the document. Therefore, to use an external image, your app must retrieve the image and store it in the document. The report viewer will try to do this for you.
Two possible answers:
First, in order for your app to package the image into the PDF, it must be able to retrieve the image from the URL you are specifying. If that URL is behind a proxy (from the perspective of your app server) and/or requires credentials to access, this will present a challenge with the default configuration of the report viewer.
If a proxy server is the issue, please see the settings to your web.config you can add below. You may also need to supply network credentials, so your app can authenticate to the proxy. There are lots of ways to solve this, but one of the easiest is to run your application as a service account on your domain that has rights to traverse your proxy. You can test this by running the site as you temporarily (should be temporary because this is a horrible security practice).
The image you are using could require credentials to access (try pulling up the image in Firefox with empty cookies and verifying whether credentials were required to access it). If it requires Windows authentication, the same solution to proxy security may apply to authentication required on the remote image. If it requires some other form of authentication, you may be better off downloading and embedding the image into your project.
It is also possible to download the image using other means in your code and convert it to a byte array for inclusion in the report. There are lots of examples of this on the web, including a Stack Overflow here.
Second, take a look at the following page:
http://msdn.microsoft.com/en-us/library/ms251715%28VS.80%29.aspx
Using external images in a
ReportViewer report is not enabled by
default. To use an external image, you
must set the EnableExternalImages
property in your code. Depending on
your network configuration, you might
also need to bypass proxy settings to
allow the external image to appear.
You can add the following settings to
the Web.config file to bypass the
local proxy. When modifying your
Web.config file, be sure to specify
the name of the proxy server that is
used in your network:
<system.net>
<defaultProxy>
<proxy usesystemdefault = "false" bypassonlocal = "true" proxyaddress = "http://< proxyservername >:80/" />
<defaultProxy>
</system.net>
Hope one or both of these helps.
Jerry

When passing external image filenames to ReportViewer parameters, pass the format like this: file://C:\app\images\pic.jpg. Anything else usually doesn't work well when deployed.

Okay, so this was our solution. The web server did not recognize its own qualified DNS name as a URL, so we had to edit the Hosts file in the C:\Windows\System32\drivers\etc folder and add the host name as localhost. The line we added to the file was:
ourserver.ourdomain.com 127.0.0.1

I don't think Adobe Reader (or maybe the PDF specification itself?) allows external content to be loaded for security purposes. I vaguely remember having a similar issue that had nothing to do with reporting services (I was dynamically generating PDFs and using variable logos and had to embed them).

Did you try a regular file path (c:/temp/somefile.bmp)? Reporting services local report reads the file from the disk and embeds it in the pdf file produced. Make sure that the identity of the app pool in IIS has read permission on the image file.
We are doing it and our images are placed in an img folder under the web site, along withe the rest of the web sites images. We avoid hard coding the path by using Server.MapPath(relative path).
Hope this helps

I fixed my problem with this:
//For local relative paths
string imgUrl = new Uri(HttpContext.Current.Server.MapPath("~/images/mylocalimage.jpg")).AbsoluteUri;
// OR
// For complete URLs
{
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; // This allows reportViewer to download image from url
string imgUrl = /* Your image URL ("http://") */;
}
//Then pass imgUrl parameter as external source of your image.

Can the report viewer get an image from a relative url? I've never used it, so best to check that assumption.
Have you tried using the Html.Content() helper to set the URL? Whenever I have issues with my urls its because I didn't use this to generate the correct url for the view.

Related

Accessing images in a different project, but in the same solution

I made this website for a client which wanted to be able to upload images and then use those images to create some dynamic content on his site. It all works fine, but now I want to isolate that administration part (where he can add images and create his content) on a subdomain.
So at the moment, I have two projects. One where images get uploaded to, and one who has to access those images (this is my problem).
I have read multiple topics related to this issue but have not found a solution, I can never get a path outside of my current project.
The only option I am thinking right now that could work is to have some kind of API on the main website, and when an image gets uploaded to the administration site, send that file over to the main site, but that seems pretty overkill knowing that my images will be on the same server.
Can this be done?
What is the cleanest/best way to achieve this?
Please note:
Saving images to the database is not an option. Uploading files on the server and then only storing the path is so much faster.
My images get uploaded at run-time, I can't use anything that relies on resources/compilation-time.
Thanks!
UPDATE (SOLUTION)
Rather than saving in the database only the name of the file (image), for example "image1.png" and then trying to retrieve the path in the other project, I ended up saving the absolute URL in the database so that I could then use that URL directly.
public static string ResolveServerUrl(string serverUrl, bool forceHttps)
{
if (serverUrl.IndexOf("://") > -1)
return serverUrl;
string newUrl = serverUrl;
Uri originalUri = System.Web.HttpContext.Current.Request.Url;
newUrl = (forceHttps ? "https" : originalUri.Scheme) +
"://" + originalUri.Authority + newUrl;
return newUrl;
}
This will give you a URL that looks like http://yourdomain/path/to/image.jpg, so you can save it directly in the database and use it as is in the other project.
The only option I am thinking right now that could work is to have some kind of API on the main website, and when an image gets uploaded to the administration site, send that file over to the main site
I think you just kind of answered your own question. That is indeed the way to go, or I should say you're on the correct direction towards a enterprise SOA architecture...you are still far from it. But, this is a good start where you start to realize that your system is growing and demanding a more robust architecture
but that seems pretty overkill knowing that my images will be on the same server.
This is a false statement because if you design it well, you can easily scale out to a different server and platform without affecting your client app(s). Let's say that in the future, the content is moved to its own server, you will only make the pertinent modifications to your "Content Service" while your client apps will not need to be changed at all, they're still pointing to the same endpoint and will never notice what's happening with the internals of the "Contents Service". What this means is that your client apps only care about getting content from the "Contents Service" without knowing where the content is actually hosted, whether in a Windows Server, a Linux server, a Sql Database, an Oracle database, in the US or China. It's not the responsibility of the client app(s) to care about how the content is handled, instead they only need to know how the content is served
Hope it makes sense. I could provide you with some links explaining the absolute benefits of such architectures

java webapp uploaded image accessing URL

My web application allows end users to upload image. After the image is saved to server, the image will then be viewable at my web site. To make the webapp easier to scale, I decide to store the uploaded image into different folder based on current time, like:
/images/upload/2011/11/30/image1.jpg
/images/upload/2011/11/30/image2.jpg
/images/upload/2011/12/29/image1.jpg
/images/upload/2011/12/29/image2.jpg
This is ok. However the image URL for end user will also include information like:
http://www.mywebapp.com/images/upload/2011/11/30/image1.jpg
which is not desireable. I am wondering whether it is possible to produce the digest for "2011/11/30/image1.jpg" as something like "8faa6933ac54cd2ae5eb575d2d966a42.jpg", save the mapping somewhere, and then serve end user with:
http://www.mywebapp.com/images/8faa6933ac54cd2ae5eb575d2d966a42.jpg
When the request for the image comes in, we look up the real image from the previously saved mapping, and serve the real image.
Is it possible to achieve the above? Or it is not relevant at all. I am using spring mvc for my application.
Thank you for your time,
George
You could write a servlet that catches those urls and pass the image to the user as a byte-stream.

AS3: Security sandbox violation

I want to go live with my site.
...but I need help with a security violation I am incurring.
I've seen various threads on this forum regarding a crossdomain.xml file to include and link to, but I don't get it... no matter what I try I still end up with the same result. You'll note below that it is not recommended to use crossdomain hacks.
FWIW, this only happens when I export a release build... I can load the php data w/out an issue in my debug/developing phase locally in Flex.
What gives? When I make a PHP based request for data I always get this error popping up:
Error #2044: Unhandled securityError:.
text=Error #2048: Security sandbox
violation:
http://alubow.com/jml_testing/viewable/alubow_project.swf
cannot load data from
http://www.alubow.com/jml_testing/foldergrab.php?ipath=assets/bitmap/portrait_thumbs/&tpath=assets/bitmap/portrait_imgs/.
at utils.php::DirectoryReader() at
alubow_project/newScroller() at
alubow_project/mainClickOut()
Is there code I need to add to get this to work? Do I need to configure the server I am using?
I will need to go live with this site soon and these errors I am getting both locally and serverside (via a browser) are unacceptable.
COULD THIS BE A PROBLEM WITH THE FLASH PLAYER I HAVE INSTALLED?
I have the debugger version of flash player 10.
jml
The problem is with the www prefix. I guess you are trying to load a page with out the www subdomain and the URL you are looking for does have that prefix.
Now, what you need to do is one of the following:
change the request url
add both www.yourdomain.com And yourdomain.com to the crossdomain.xml
call the url dymanicaly. this is the best solution but needs some more work. you can get it done using ExternalInterface and connection to JS here. OR you can use the BrowserManager.
Enjoy!
It may be because your app is requesting from www.alubow.com when hosted from alubow.com, which triggers a request for http://www.alubow.com/crossdomain.xml, which doesn't exist. You could refer to your app as www.alubow.com/jml_testing/viewable/alubow_project.swf and avoid the error.
Alternately, you could add a crossdomain.xml file to www.alubow.com.
I know this is weird but for local files loaded through the flash player you probably just need to hit this page. Look near the top right for something that looks like an example image. It's actually a Flex application. Click successive tabs until you read the Global Security Settings panel (currently 3rd from the left, with an image of a globe and padlock). Select the "Edit locations" menu, and choose "Add location". You can then add your swf or your folder of swf's into the whitelist and they'll be able to access outside resources magically.

Using HttpModule to Display Images

I have an HttpModule that displays images that follow a certain URL pattern. For example, /images/employees/jason.jpg is handled by the module, but all other images aren't. It works just fine on my local machine (Cassini and IIS 7). However, the IIS6 production server isn't working. I've had the hosting company map the images to the ASP.NET worker process. Now, all images are showing that they can't render except for the images that should be rendered by the module. They are working correct.
I ran an HttpWatch instance on one of the files and received the following error:
ERROR_HTTP_INVALID_SERVER_RESPONSE
Any ideas?
Final Answer:
The module needed to be updated to transmit server files. So, I added an else to my original if and checked to see if it was an image type (by using a utility method) then use Response.TransmitFile() to pass on the file to the browser.
I then ran into a spacing issue with the images. This was because I forgot that I had .aspx files registered as an image type to perform the testing. So each page would crash during the debug process or add padding that was established from CSS. Doh!
Everything is just peachy now. Thanks to all!
There's doesn't seem to be anything particularly wrong with your module, so the issue must be coming from somewhere else. Have you got security that might be blocking the images? What actually gets returned when you request a static file?
I'd suggest seeing what gets returned (and its headers) using something like firebug to check things like the response code, content type, the actual raw response, etc...
check your web.config IIS6 / IIS7 have different places to add modules and depends on what mode your IIS7 is running in.
http://arcware.net/use-a-single-web-config-for-iis6-and-iis7

Web File Security best practices for ColdFusion 8 in IIS6 or IIS7

Let's say we have a web site with a CF app that was written in-house.
Assume that:
Server 2003 IIS6 or 2008 IIS7 will be used
ColdFusion 8 will be used
Directory browsing is denied
SSL is required to connect
The account login process is secure (yeah I know that is a whole other
ball of wax but that concept is discussed ad nauseum on the web).
Say I have a file at https://domain.com/folder1/folder2/ with a name like picture92352.ext imagine it as a jpg or pdf or whatever. The entire path between the domain name and the file varies widely in naming structure, depth, etc. Files are not all lumped together in one folder.
The app restricts links by user such that a user would have to have access to that file to find it in the first place but as it stands now if a person knew the full URL to that file they could retrieve it without logging in to the app. It's the classic security by obscurity situation. A random person isn't likely to find a file they shouldn't get to but once someone is given access they know how to access it from another PC where their actions might not be traced back to them.
How do I restrict access to these files before someone logs in and still make them accessible to outside users after they log in? Is there a way to do it with permissions only or is the only answer to have code dynamically moving files around at the time of the request or is there some obvious step I'm not even thinking of?
Let me clarify this slightly. No matter how the file is presented on a page a user can use the browser IE, Firefox, etc to examine the URL the file comes from. If the image is a link there is always copy shortcut in the right click menu for IE and the same functionality in FF is called copy link location. If the image is displayed inline as part of the page an IE user can right click and choose properties to see the URL, in FF the same functionality is present to see properties but there is an even quicker more convenient option labeled copy image location. Once a user knows the URL to a file if the location or file name doesn't change they can use that URL without authenticating in the CF app.
If I change the NTFS/share permissions so that IUSR can't see the content then my CF app and IIS can't push it. What strategy do I use to provide the file in the CF app that doesn't leave this hole open?
You could write a CFM page that serves up the images. Then you just make sure they are authenticated inside the CFM.
<!-- something like this -->
http://localhost/GetFile.cfm?file=foobar.jpg
In GetFile.cfm, you would do something like:
<!-- the filename part is what the browser will pre-popualate the file name in the download dialog as -->
<CFHEADER name="Content-disposition" value="attachment;filename=picture92352.ext">
<CFCONTENT type="text/plain" file="\\fileserver\folder1\folder2\picture92352.ext">
Take a look at the various MIME types.
If you wanted to do something similar but keep a more natural URL, I think you would need to leverage the Java servlet underpinnings of ColdFusion to create a handler for any URL matching a certain pattern.

Resources