Web.config urlMappings - works for local pages, not remote pages - asp.net-mvc

I have a MVC4/.Net 4 website running on IIS 7.5. In my web.config file I have the following in my block:
<urlMappings enabled="true">
<add url="~/2013calendar" mappedUrl="~/CustomerService/RequestPocketCalendar" />
<add url="~/teachers" mappedUrl="http://www.somexternalsite.com/teachers/" />
</urlMappings>
The local redirects all work great, but anything that is redirecting off the site, such as the /teachers link in the above example return "http://www.somexternalsite.com/teachers" is not a valid virtual path.
What am I missing here?

If I'm not mistaken, the mappedUrl field is a path relative to the root of the application. As such, "http://www.somexternalsite.com/teachers/" is not valid.
If you'd like to configure this to redirect, I would just create a "Teachers" action in your root controller, then use the following:
return Redirect("http://www.somexternalsite.com/teachers");

Well I ended up creating a page to handle external redirects such as follows:
redirect.aspx
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
var page = Request.QueryString["page"];
Response.Redirect("http://"+page);
}
</script>
So in my web.config I have external files referenced as such:
<add url="~/teachers" mappedUrl="~/redirect.aspx?page=www.somexternalsite.com/teachers/" />
Works great!

Related

Why is 404 Custom Error working but 500 Custom Error not?

I have implemented CustomErrors in my web.config. The 404 error works as intended, the 500 errors simply show an empty default layout page with the standard generated .NET HTML output in the RenderBody area.
The code in the web.config is:
<customErrors mode="On">
<error statusCode="404" redirect="~/404.html"/>
<error statusCode="500" redirect="~/500.html"/>
</customErrors>
404 can be seen here: http://www.airportcars-gatwick.com/i-do-not-exist
500 can be seen here: https://taxis.gatwickairport.com/Book?Q=9fa5-514e-4c3a-972f8baee58fa2b9
(Both files are in place on the server at the same root location)
This is the layout page with HTML injected into the RenderBody
</div>
</header>
<!-- //Header -->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Error</title>
</head>
<body>
<hgroup>
<h1>Error.</h1>
<h2>An error occurred while processing your request.</h2>
</hgroup>
</body>
</html>
<!-- Footer -->
<footer class="footer teal" role="contentinfo">
<div class="wrap">
..etc...
Not sure what I'm missing?
It appears the issue was with a default configuration of my GlobalFilters.
GlobalFilters is a way to associate an attribute with every Action method in the ASP.NET MVC application. I guess my project had automatically taken care of that for me.
Within my app_start folder within the FilterConfig.cs file:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
So by commenting out the RegisterGlobalFilters line in the Global.asax.cs file, the issue was resolved.
protected void Application_Start()
{
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); // Comment out
Hope this helps if anyone else experiences the same behaviour.

Accessing CDN bundles on different ASP.Net MVC site

This is a follow-up question to this: ASP.Net MVC 5 - Deploy separate CDN site with bundled JavaScipt and CSS
I want to serve up my JavaScript and CSS bundles from a second ASP.Net website, so I have done the following.
Main website (ASP.Net MVC website that has not JS or CSS resources)
CDN website (ASP.Net MVC website that has all JS and CSS resources but not much else)
CDN Website Web.config extract
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
CDN Website Bundle Config
public static class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
}
}
Main Website Bundle Config
public static class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new StyleBundle("~/Content/css", "http://[CDN website]/Content/css"));
//BundleTable.EnableOptimizations = true;
}
}
Main Website Layout View
<!DOCTYPE html>
<html>
<head>
#Styles.Render("~/Content/css")
</head>
<body>
#RenderBody()
</body>
</html>
Result
The HTML produced by the main website doesn't render the <link> tag for the CSS. However, if I turn on bundle optimizations (see commented out code in Main Website Bundle Config), then the <link> tag appears but looks like this:
<link href="/Content/css?v=" rel="stylesheet">
Navigating to http://[CDN website]/Content/css in the browser loads the appropriate CSS.
Navigating to http://[Main website]/Content/css in the browser loads an empty page.
Am I doing this the incorrectly? I don't want to reference the CDN website URL directly because I want the versioning that comes with the MVC bundler.
I ended-up using the following solution for the CDN website.
https://stackoverflow.com/a/26402383/2663033
The main website then used the appropriate MVC route of the CDN website for the style "href" and the script "src", which redirected to the appropriately versioned content or script bundle.

How to disable open ASP.NET MVC site in IFrame?

As I have already mentioned in topic, I have a MVC site and I need to disable loading it into IFrame.
I have created simple page for testing purpose and I try to load into two IFrames my site and Google.com. I can see that my site is loaded but Google isn't. It means that it's necessary to change something in my MVC site.
<!DOCTYPE html>
<html>
<body>
<iframe src="http://localhost:61831/" width="1200" height="800">
<p>Your browser does not support iframes.</p>
</iframe>
<iframe src="http://google.com" width="1200" height="800">
<p>Your browser does not support iframes.</p>
</iframe>
</body>
</html>
So what and where in MVC site I have to write to achieve that?
It is possible to use X-Frame-Options HTTP header attribute to avoid ASP.NET MVC application be opened in IFrame.
There are several different way to insert this attribute to HTTP header:
1.Configure IIS to add this attribute to all HTTP responses
2.Set this attribute in every necessary action method of every controller
public class HomeController : Controller
{
public ActionResult Index()
{
Response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
return View();
}
}
3.Create C# attribute in a way described here and apply it to action methods and controllers
[HttpHeader("X-Frame-Options", "SAMEORIGIN")]
public class HomeController : Controller
{
public ActionResult Index()
{
}
}
4.Set this attribute in Global.asax file
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
...
}
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
Response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
}
}
Simple and quick Solution is to add following in Global.asax -
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
Response.AddHeader("X-Frame-Options", "SAMEORIGIN");
}
Then give a try with iframe. Pages will not open in iframes. HTH.
You can also add an entry in web.config:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
...
</system.webServer>
You can configure IIS to always append the X-Frame-Options SAMEORIGIN header in it's responses.
From IIS Management Console, select your application.
In the main panel, double click Http Response Headers.
Click Add from the upper right pane.
Set the name to X-Frame-Options and the value to SAMEORIGIN then
click OK.
This should prevent your site from being loaded into an iframe on a different host, without using any javascript or any extra code.
See developper.mozilla.org for the header documentation and technet.microsoft.com for IIS' configuration.
As DrewMan suggested, you want to use X-Frame-Options header.
I would suggest you to download Nuget Package NWebsec and there's MVC specific package. Also check out the configuration part.

Mvc3 web app routing directly on index.cshtml

I have created and host nvc3 web app
now problem is when I open my www.abc.com
it is opening index.cshtml i.e home page of mvc web app
but I dont want that to be open when I open www.abc.com
I have one static page called index.htm should be open first
in mvc3 Global.asax code:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
How can I render to http://www.abc.com/mypage.html ?
what should I please help.
ashuthinks,
Based on your revised comments for the question. If you just want to show the 'Under contruction' type page with no links, then you can modify the web.config and add an app_offline.htm file. here's what those changes would look like:
web.config (bare bones):
<?xml version="1.0"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
app_offline.htm:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Your site title</title>
</head>
<body>
<div>
<span>Your Company name</span>
<h1>Sorry, server maintenance in progress </h1>
<h2>Please contact John Doe on 000 123 456789 for further information</h2>
</div>
</body>
</html>
when you need to put the site live, simply rename the above files to web.config_offline and app_offline.htm_offline and bring your 'normal' web.config into play. There are of course many ways to skin this cat but this has worked well with previous projects that I've worked on.
see:
http://weblogs.asp.net/scottgu/archive/2006/04/09/442332.aspx
for further details.

Trying to Make the Simplest OpenID using DotNetOpenAuth Login in asp.net

I've downloaded the Visual Studio 2010 Template associated with the http://www.dotnetopenauth.net/. I can get that to work as advertised. I am not starting a project from scratch and I don't want to put a lot of time into integrating all the web.config, handlers, etc. into my application to get OpenID working for me. The doc says that I should be able to make a one line implementation using a button and a user control. I believe I have done that and I get an error.
Here is what I've done.
Create empty asp.net web project
Add DotNetOpenAuth.dll to bin and reference it
Add user control registration to top of page
Create Button on page that calls user control.
When I run it and press the button, I get:
"Precondition failed: this.Identifier != null No identifier has been set."
I know there must be more to it than this, but I just don't get it. Can someone explain further what I need to do?
Thanks,
<%# Page Language="C#" %>
<%# Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void LoginId_Click(object sender, EventArgs e)
{
OpenIdTextBox1.LogOn();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="LoginId" runat="server" Text="Button" onclick="LoginId_Click" />
<rp:OpenIdTextBox ID="OpenIdTextBox1" runat="server" />
</div>
</form>
</body>
</html>
You you actually typing an identifier in the box before clicking the button? You must.
And you can avoid the nasty error for people who forget to type an identifier by adding a RequiredFieldValidator control that points to the text box and then checking that if (Page.IsValid) in your button's click handler before calling LogOn.
Hopefully this helps. Have you considered using the OpenIdLogin control? If you're shooting for easiest to add, that's the easiest, as you don't have any code at all -- just the one tag.
Also, be sure to add ValidateRequest="false" to your <%# Page %> tag at the top of your login page. Otherwise your users will see occasional random failures because ASP.NET incorrectly interprets some OpenID authentication responses to be attacks.
So for example, if the top line of your .aspx was:
<%# Page Language="C#" AutoEventWireup="True" CodeBehind="login.aspx.cs" Inherits="OpenIdRelyingPartyWebForms.login" %>
Make it
<%# Page ValidateRequest="false" Language="C#" AutoEventWireup="True" CodeBehind="login.aspx.cs" Inherits="OpenIdRelyingPartyWebForms.login" %>

Resources