Calls for files are made in the wrong file path - asp.net-mvc

Hi I am trying to build an Angular App and I have the following situation in ASP.NET MVC.
I have created an App folder in the root directory of the project that contains the following:
styles folder
scripts folder
images folder
index.html file
Then instead of returning a View in my HomeController Index Action I returned the following:
public ActionResult Index()
{
return File(Server.MapPath("/App/index.html"), "text/html");
}
the index.html has a the following style added:
<link rel="stylesheet" href="styles/main.css">
When I run the app the index.html gets retrieved but I get an error inside of retrieving the style file:
http://localhost:57826/styles/main.css
For some reason instead of it looking in the the following path http://localhost:57826/App/styles/main.css it looks in the path mentioned above.
I then tryed to intercept the calls and get the files from the correct path by creating a custom router like this:
routes.MapRoute(
name: "Style",
url: "styles/{*path}",
defaults: new { controller = "Www", action = "Style" }
);
public class WwwController : Controller
{
public ActionResult Style(string path)
{
byte[] content = this.GetContent(this.CorrectPath(path, "css"));
var result = new FileContentResult(content, this.GetContentTypeFor(path));
return result;
}
private string CorrectPath(string path, string folder)
{
return Server.MapPath("/App/" + folder + "/" + path);
}
private byte[] GetContent(string path)
{
byte[] readAllBytes = System.IO.File.ReadAllBytes(path);
return readAllBytes;
}
private string GetContentTypeFor(string path)
{
return System.Web.MimeMapping.GetMimeMapping(Path.GetFileName(path));
}
}
But my solution does not seem to work.The Style action is not called.Can anyone tell me how can I solve my problem

Why are you breaking the MVC model by not allowing your view to do the presentation work? Simply do this:
public ActionResult Index() {
return View();
}
Then put whatever content you need into Views/Home/Index.cshtml:
<link rel="stylesheet" href="styles/main.css">
#* Add link tags, javascript, etc. *#
Or just use a vanilla ASP.NET site.

Related

Image not displaying in ASP.NET MVC

In an ASP.NET MVC application, file is successfully saved to a folder and its URL is saved to SQL database. Having problem in loading file in a browser from folder using this URL. Code implementation is:
[HttpPost]
[ActionName("UploadPhoto")]
public ActionResult UploadPhoto(HttpPostedFileBase photoPath)
{
var fileName = Path.GetFileName(photoPath.FileName);
string path;
if (photoPath.ContentLength > 0)
{
path = Path.Combine(Server.MapPath("~/Images/photos"), fileName);
photoPath.SaveAs(path);
return RedirectToAction("CreateWithImage", new { path = path });
}
return View();
}
public ActionResult CreateWithImage(string path)
{
employee em = new employee();
em.districts = new SelectList(hc.districts, "name", "name");
em.photoPath = path;
return View(em);
}
file (image) is rendered in a view as:
#model HRMS.Models.employee
<dd>
#Html.Image(#Model.photoPath)
</dd>
Extension method implementation for #Html.Image is:
namespace HRMS.CustomeHTMLHelper
{
public static class CustomHtmlHelper
{
public static IHtmlString Image(this HtmlHelper helper,string src)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
}
}
}
When View is called, I see a broken link for the image. HTML(with correct file path) for the loaded page (View) is seen as:
<dd>
<img src="/App_Data/photos/1.png" />
</dd>
When I try to run the physical path to the image in the browser i.e., <b>Requested URL</b> http://localhost:57852/App_Data/photos/1.png, it is throwing HTTP Error 404.8 - Not Found Error.
Where could I be wrong? Please help.

How to download a file to client from server?

I have an MVC project where I'd like the user to be able to download a an excel file with a click of a button. I have the path for the file, and I can't seem to find my answer through google.
I'd like to be able to do this with a simple button I have on my cshtml page:
<button>Button 1</button>
How can I do this? Any help is greatly appreciated!
If the file is not located inside your application folders and not accessible directly from the client you could have a controller action that will stream the file contents to the client. This could be achieved by returning a FileResult from your controller action using the File method:
public ActionResult Download()
{
string file = #"c:\someFolder\foo.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
return File(file, contentType, Path.GetFileName(file));
}
and then replace your button with an anchor pointing to this controller action:
#Html.ActionLink("Button 1", "Download", "SomeController")
Alternatively to using an anchor you could also use an html form:
#using (Html.BeginForm("Download", "SomeController", FormMethod.Post))
{
<button type="submit">Button 1</button>
}
If the file is located inside some non-accessible from the client folder of your application such as App_Data you could use the MapPath method to construct the full physical path to this file using a relative path:
string file = HostingEnvironment.MapPath("~/App_Data/foo.xlsx");
HTML:
<div>#Html.ActionLink("UI Text", "function_name", "Contoller_name", new { parameterName = parameter_value },null) </div>
Controller:
public FileResult download(string filename) {
string path = "";
var content_type = "";
path = Path.Combine("D:\file1", filename);
if (filename.Contains(".pdf"))
{
content_type = "application/pdf";
}
return File(path, content_type, filename);
}

Redirect with ASP.NET MVC MapRoute

On my site, I have moved some images from one folder to another.
Now, when I receive a request for old images '/old_folder/images/*' I want to make a permanent redirect to new folder with these images '/new_folder/images/*'
For example:
/old_folder/images/image1.png => /new_folder/images/image1.png
/old_folder/images/image2.jpg => /new_folder/images/image2.jpg
I have added a simple redirect controller
public class RedirectController : Controller
{
public ActionResult Index(string path)
{
return RedirectPermanent(path);
}
}
Now I need to setup proper routing, but I don't know how to pass the path part to the path parameter.
routes.MapRoute("ImagesFix", "/old_folder/images/{*pathInfo}", new { controller = "Redirect", action = "Index", path="/upload/images/????" });
Thanks
I would do in next way
routes.MapRoute("ImagesFix", "/old_folder/images/{path}", new { controller = "Redirect", action = "Index" });
and in controller like that
public class RedirectController : Controller
{
public ActionResult Index(string path)
{
return RedirectPermanent("/upload/images/" + path);
}
}
first download and install RouteMagic package from this link , then redirect your old address to the new address Like the below code :
var NewPath = routes.MapRoute("new", "new_folder/images/{controller}/{action}");
var OldPath = routes.MapRoute("new", "old_folder/images/{controller}/{action}");
routes.Redirect(OldPath ).To(NewPath );
for more information please check out the following link
Redirecting Routes To Maintain Persistent URLs
Answer above using RouteMagic is a good idea, but the example code is wrong (it's included in Phil's post as a bad example).
From the RouteMagic Github demo site global.asax.cs:
// Redirect From Old Route to New route
var targetRoute = routes.Map("target", "yo/{id}/{action}", new { controller = "Home" });
routes.Redirect(r => r.MapRoute("legacy", "foo/{id}/baz/{action}")).To(targetRoute, new { id = "123", action = "index" });
If you specify two routes, you will be setting up an extra mapping that will catch URLs which you don't want.

Styles.Render and Scripts.Render does not render properly in different areas

I have at least 3 areas in my mvc project.
All css and js files are located in Css folder and JS folder respectively at the root "~/css/" ~/js/
I register the bundle inside Global.asax file like this:
BundleTable.Bundles.Add(new StyleBundle(CssVirtualPath("mastercss"))
.Include(Css("bootstrap.min.css"), new CssRewriteUrlTransform())
.Include(Css("bootstrap-responsive.min.css"), new CssRewriteUrlTransform())
.Include(Css("normalize.css"), new CssRewriteUrlTransform())
.Include(Css("media.css"), new CssRewriteUrlTransform())
.Include(Css("jquery-ui-1.8.24.custom.css"), new CssRewriteUrlTransform())
.Include(Css("icons.css"), new CssRewriteUrlTransform())
.Include(Css("MetroJs.css"), new CssRewriteUrlTransform())
);
private static string CssVirtualPath(string filename)
{
return string.Format("~/bundle/css/{0}", RemoveSpecialChars(filename));
}
private static string Css(string filename)
{
filename = RemoveSpecialChars(filename);
return string.Format("~/css/{0}", filename);
}
private static string RemoveSpecialChars(string value)
{
return value.Replace("/", "").Replace(#"\", "").Replace("~", "");
}
At Area 1/Login page, I'm calling the bundle like this:
#Styles.Render("bundle/css/mastercss")
Equivalent on page source is:
<link href="/bundle/css/mastercss" rel="stylesheet"/>
And it works fine. But after I logged in, the profile page (view) rendering fails:
Area 1/User
Same code was used:
#Styles.Render("bundle/css/mastercss")
Equivalent on page source is:
<link href="/Area1/User/bundle/css/mastercss" rel="stylesheet"/>
And it fails to load... What should I do? I've been looking for answers, but found no luck.

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...

Resources