images not showing after website deployed to IIS - asp.net-mvc

I have img tag in my view as below
<img src="#Url.Action("Images", "MemberImage", new { image = TempData["id"]+".jpg" }) "
alt=" " style="width: 100px;height:150px" />
My controller is
public ActionResult Images(string image)
{
var root = #"\\server1\PHOTOGRAPHS received\photos";
var path = Path.Combine(root, image);
path = Path.GetFullPath(path);
if (!path.StartsWith(root))
{
// Ensure that we are serving file only inside the root folder
// and block requests outside like "../web.config"
throw new HttpException(403, "Forbidden");
}
return File(path, "image/jpeg");
}
This is working perfectly in my local system but when i deployed to IIS the picture is not displaying.
The server where IIS installed has access to this path
Any other configuration i need to do?

The server may have permission to the shared directory, but it would be worth checking that the account that the website runs under (the one the app pool is using) has access to the share.

Related

MVC url routes not working after deployment on IIS

I have a MVC app that works just fine on local, but when deployed on IIS all the routes return 404 not found.
My browser shows me in some cases the layout but doesn't bring the data for that view and instead of that returns 404.
I will show you a method that works fine on local but in IIS fails.
[Route("/Customer/CustomerDetails/{id}")]
public async Task<IActionResult> CustomerDetails(int id)
{
ApiResult<eCOM_Backend.Api.Responses.Customer> apiResult = await _customerApiMethods.CustomerDetailsAsync(id);
eCOM_Backend.Api.Responses.Customer customerFromBackend = null;
if (!apiResult.HasException)
{
customerFromBackend = apiResult.Result;
}
else
{
return RedirectToAction("Error", "Error", new { reason = apiResult.Exception });
}
CustomerViewModel customer = customerFromBackend.ToCustomerViewModel();
return View(customer);
}
When I call this method like: xxx/Customer/CustomerDetails/123 i get page not found.
I have tried lots of solutions(modified the appsettings.json, web.config etc.) but nothing worked so far.
Thanks a lot!
Looks like this is dotnet core. Make sure to provide correct physical path when you publish your app to IIS. Like inetpub\wwwroot\YourAppName. In IIS right click on your web app >Manage Website>Advanced Settings and make sure physical path ends on your app folder not yourApp\someOtherFolder

can't read images in asp.net core website

I am having an asp.net core api project and i am trying to read images that exist in my web site but i am getting 404 not found error.
Code line below that throws an exception when executing GetStreamAsync method:
foreach (var item in imgUrls)
{
// read from remote image drive
using (HttpClient c = new HttpClient())
{
using (Stream s = await c.GetStreamAsync(item))
{
// do something with the stream...
}
}
}
The image url is correct, but when i try to paste it in another tab while the app is running, i don't see the image displayed in my browser. am i missing an asp.net configuration or something that prohibit content files such as images from being displayed through the api response.
Note: the imageUrls we send is FQDN urls, for example the url looks like:
http://localhost:25071/images/test.jpg
looking forward to your help.
This is how i fixed the issue, i didn't enable directory browsing in my asp.net core web api.
So i added my static files (images) folder under wwwroot and added below code in startup.cs to configure/allow directory browsing to images folder and app starts to deliver and show images.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// few standard lines in here.....
// enable directory browsing
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot\images")),
RequestPath = new PathString("/images")
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot\images")),
RequestPath = new PathString("/images")
});
}
enjoy!

PDF JS, from file location

I have successfully set up using the viewer with the following code:
protected void btnShowPDFS_OnClick(object sender, EventArgs e)
{
// Display all files.
string[] files = Directory.GetFiles(#"D:\Reports\2014\July\", "*.PDF");
var pdfNames = new List<string>();
foreach (string file in files)
{
string fileName = Path.GetFileName(file);
string queryString = "/web/viewer.html?file=" + System.Web.HttpUtility.UrlEncode("../July/" + fileName);
pdfNames.Add(queryString);
}
listView.DataSource = pdfNames;
listView.DataBind();
}
Now, this all works fine if all my PDF's are in a folder within the website (i.e localhost). However, how do i point the view to either a network share, or just another folder on the same machine, but outside of IIS?
A browser's XMLHttpRequest might have a restrictions for local files access (Firefox has more relaxed policy for local file than other browsers).
PDF.js is using XHR; and PDF.js also allows "load" files from a typed array (Uint8Array). You can use the latter in your solution. Notice the Internet Explorer (WebBrowser control) has window.external that can be used to transmit the data from the host application, see http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting(v=vs.110).aspx

File.Move on client machine Asp.net MVC

Silly question but here goes...
Is it possible to write an intranet windows auth asp.net mvc app that uses File.Move to rename a file on a users machine? Or will the File.Move and using Path.GetDirectory and other System.IO functions look on the IIS server directory structure instead of the client machine?
[HttpPost]
public ActionResult Index(HttpPostedFileBase file, string append)
{
try
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
DirectoryInfo filepath = new DirectoryInfo(file.FileName);
string parentpath = Path.GetDirectoryName(filepath.FullName);
DirectoryInfo searchablePath = new DirectoryInfo(parentpath);
var directories = searchablePath.GetFiles("*", SearchOption.AllDirectories);
foreach (FileInfo d in directories)
{
if (!string.IsNullOrEmpty(append) && !d.Name.Contains(append))
{
string fName = Path.GetFileNameWithoutExtension(d.Name);
string fExt = Path.GetExtension(d.Name);
System.IO.File.Move(d.FullName, Path.Combine(d.DirectoryName, fName + append + fExt));
}
}
}
}
catch (Exception ex)
{
}
return View();
}
I have tried this but am getting a filenotfoundexception.
Any ideas?
The ASP.NET code runs on the server, so it will look at the files on the server.
You can't rename a file on the client machine, however it would be possible to rename a file on the computer that is used as client, if:
the server and computer are on the same network
the server knows the name of the computer
the server knows which folder to look for in the computer
the folder is shared with the user account running the ASP.NET code on the server with enough privileges to change the name of a file
In that sense the computer is not a client to the server, but the server communicates directly with the computer via the file system, not via IIS.
These will indeed work only on the server.
You may look at the various file and filesystem related specifications for client-side javascript APIs provided by the user's browser:
http://www.w3.org/TR/FileAPI/
http://www.w3.org/TR/file-system-api/
http://www.w3.org/TR/file-writer-api/

Deleting an uploaded file from the server in ASP.NET MVC3

I am trying to upload files to a folder from the admin side like a CMS.
The front-end will display links to download the file.
On the admin end, I would like to not only delete the reference to but also remove the actual file from the server.
Here is the part of my controller that saves the uploaded file:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
ViewBag.fileName = fileName.ToString();
return RedirectToAction("Create", new {fileName = fileName });
}
return RedirectToAction("Index");
}
In the Create view, the admin is then allowed to enter other details about the document and that is stored on a table along with the fileName.
Now I need to be able to link to that document name like document.pdf. Am I even able to link to an uploads folder under App_Data folder?
Also, how do I remove the file and not just the table row on doing delete?
Create a separate controller to handle the downloading of the file. It also prevents your users to hotlink directly to the files.
public ActionResult GetDocument(String pathName)
{
try
{
Byte[] buffer = DownloadMyFileFromSomeWhere(pathName);
FileContentResult result = new FileContentResult(buffer, "PDF"); // or whatever file ext
// these next two lines are optional
String[] folders = pathName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
result.FileDownloadName = folders[folders.Length - 1];
return result;
}
catch (Exception ex)
{
// log the error or something
}
return new HttpNotFoundResult();
}
Where DownloadMyFileFromSomeWhere(string) should be able to retrieve the byte-array file from some storage like a blob or even the local server. It can look something like:
private Byte[] DownloadMyFileFromSomeWhere(string pathname)
{
Byte[] file = System.IO.File.ReadAllBytes(Server.MapPath(pathname));
return file;
}
For the Admin side, you can do the same approach: Write a separate controller to delete the file and its entry in the database.
Some notes:
If you have rights to save a file somewhere, you should also have the rights to delete it. You can use normal file operations to do this.
IIS should block you from linking to a file under App_Data. You have a couple of options:
Create an action that reads the file from that location and streams it back to the browser
Store in a different location - somewhere that the user will actually have access to.
The benefit of the first option is that you can easily add authentication, etc. to your action to secure access to the files, whereas the second option would require you to add a web.config in the folder with the appropriate roles and access rights. However, on the other hand, you'll have to supply appropriate headers in your action method so the browser knows what to do with the file, rather than letting IIS figure it out for you.

Resources