ASP.NET WebPages use html extension - asp.net

I'm trying to use ASP.NET WebPages to make sense of an existing site which uses static .html files (about 500 of them). Unfortunately, my SEO person is requiring that the site maintains its existing directory / filenames, so I need to use .html.
After finding this example, I tried adding the extension in web.config under compilation/buildProviders/ as:
<add extension=".html" type="System.Web.WebPages.Razor.RazorBuildProvider"/>
And adding an Assembly as well:
<add assembly="System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
This still doesn't render the page. It is simply output as source. I also created a Global.asax at the root of the project and added this under Application_Start():
System.Web.Razor.RazorCodeLanguage.Languages.Add(
"html", new System.Web.Razor.CSharpRazorCodeLanguage());
System.Web.WebPages.WebPageHttpHandler.RegisterExtension("html");
Still had no effect. Unfortunately, I'm drawing a blank on Google.

I happened upon this question while trying to solve the same problem - although in my case, for curiosity's sake.
Here's what you need in your web.config file:
<system.web>
<compilation>
<buildProviders>
<add extension=".html"
type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor"/>
</buildProviders>
</compilation>
</system.web>
<system.webServer>
<handlers>
<add name="Html" verb="*" path="*.html"
type="System.Web.Webpages, WebPageHttpHandler"/>
</handlers>
</system.webServer>
This isn't enough on its own, though! We need to register the extension with WebPageHttpHandler.
Normally, you'd be able to do stuff like this in the _AppStart file - unfortunately, when the application starts (i.e when _AppStart executes), it iterates over the items in the SupportedExtensions of WebPageHttpHandler, so we can't actually register the extension in AppStart.
What I did is I made a new .dll assembly with the PreApplicationStartMethod attribute, as seen here, but you can also do it inside the Global.asax file's Application_Start method.
Finally, we also need to add "html" as an extension to the RazorCodeLanguage.Languages dictionary, so that the Razor engine can figure out how to compile the template.
Example Global.asax file:
<%# Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
System.Web.WebPages.WebPageHttpHandler.RegisterExtension("html");
var languages = System.Web.Razor.RazorCodeLanguage.Languages;
languages.Add("html", languages["cshtml"]);
}
</script>

You want to use routing. Are you using webforms or MVC?
Global.asax is a good start. Add the complete code here:
namespace Name
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("Route1", "OldPage.html", "~/NewPage.aspx");
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
Obviously you don't want to manually add 500 routes but you can add url filters.
See: http://msdn.microsoft.com/en-us/library/cc668201.ASPX
ASP.NET routing enables you to use URLs that do not have to map to
specific files in a Web site.

Related

Detect ASP.NET Session Timeout - ASP.NET_SessionId method not working

I'm trying to detect Asp.NET Session Timeout to redirect user to a timeout page; i've checked various methods, most of them similar to
http://aspalliance.com/520_Detecting_ASPNET_Session_Timeouts.2
(if Session.IsNewSession and ASP.NET_SessionId cookie exists, then is a timeout)
The problem is that the "ASP.NET_SessionId" cookie is always present for me, even if i just started debugging, thus giving me always a false timeout flag when starting the web site for the first time.
UPDATE:
For testing, i've just created an Empty Asp.NET Web Application with following codes:
BasePage.cs
using System;
using System.Web.UI;
namespace TestApp.classes
{
public class BasePage : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Context.Session != null)
{
if (Session.IsNewSession)
{
string szCookieHeader = Request.Headers["Cookie"];
if ((null != szCookieHeader) && (szCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
{
Response.Redirect("sessionTimeout.htm");
}
}
}
}
}
}
Global.asax
using System;
namespace TestApp
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Session_Start(object sender, EventArgs e)
{
var a = "";
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
var b = "";
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
WebForm1.aspx
using System;
using TestApp.classes;
namespace TestApp
{
public partial class WebForm1 : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<sessionState timeout="1"></sessionState>
</system.web>
</configuration>
Then Hit F5, and i will be redirected to sessionTimeout.htm. Why?
You don't have to use cookie when you develop your website. There are other ways to store data, e.g. you can store the data specific to a user in database
Note that "Cookieless = false" attrubute of SessionState element in web.config which means the sessionID of the current session will be saved in the client machine as a cookie
<sessionState cookieless="true" />
Default settings for ASP.NET session state are defined in the machine.config file and can be overridden in the web.config file in the application's root folder. By ensuring that the above line appears in the root web.config file, you enable cookieless sessions
Refer http://msdn.microsoft.com/en-us/library/aa479314.aspx
So check only for Session.IsNewSession and disable cookie

What is wrong with my .net routes?

I have followed a few tutorials online and they all seem to show the same logic for .net routing using ASP.net web forms. When I execute the URL below I get a 404 error. Test.aspx is in the root folder of this application.
http://www.mydomain.com/member/abc
Here is my global.asax contents:
<%# Application Language="C#" %>
<%# Import Namespace="System.Web.Routing" %>
<script runat="server">
void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute(
"TestABC",
"member/{name}",
"~/Test.aspx");
}
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown
}
void Application_Error(object sender, EventArgs e)
{
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
}
void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
}
</script>
Is there something I need to do with my web.config file?
Any help is greatly appreciated.
I'm guessing that your routing module is not triggered when you hit the iis server.
As a test to verify that this is the cause : change your webconfig to run all managed modules upon a request.
You need to set this :
<modules runAllManagedModulesForAllRequests="true">
If that solved it you can go read this resource on why to not do that :)

Routing and Ninject gives 404

I'm trying to setup routing in my web application.
It doesn't seem to work with Ninject however. If I comment all the Ninject in my Global.asax, the route works like a charm.
With Ninject in the file, I just get a 404 "The resource cannot be found" when trying to open the route page.
Heres what is in my Global.asax code:
<%# Application Language="C#" Inherits="Ninject.Web.NinjectHttpApplication" %>
<%# Import Namespace="Infrastructure.Storage" %>
<%# Import Namespace="Ninject" %>
<%# Import Namespace="Ninject.Modules" %>
<%# Import Namespace="System.Web.Routing" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown
}
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
}
void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
}
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new SiteModule());
return kernel;
}
public class SiteModule : NinjectModule
{
public override void Load()
{
//Bind<ILogger>().To<NLogger>().InSingletonScope();
//Bind<IAuthentication>().To<Authentication>();
Bind<ISession>().To<LinqToSqlSession>();
Bind<IReadOnlySession>().To<LinqToSqlReadOnlySession>();
//Bind<IReporting>().To<LinqToSqlReporting>();
}
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("City", "Cities/{id}", "~/test2.aspx");
}
</script>
Anyone have an idea for what could be wrong?
When you use the NinjectHttpApplication class for your asax, you need to change the way the applicationStart & applicationEnd are called.
What's happening is .net automatically wires the methods above to the corresponding events. Because the NinjectHttpApplication already handles the Application_Start, your method won't get called, hence your routes are not registered. You need change that method to
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
RegisterRoutes(RouteTable.Routes);
}

Exception Handling in IIS7 Integrated Pipeline Mode

I have an application hosted on IIS7 running in Integrated mode. I'm handling errors by putting the following into Web.config:
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace"
defaultResponseMode="ExecuteURL" defaultPath="/Error.aspx">
<remove statusCode="500" />
<error statusCode="500" path="/Error.aspx" responseMode="ExecuteURL" />
</httpErrors>
(Because this is Integrated mode the <customErrors> block is not used.)
I want to automatically send emails every time an exception is generated. But the problem is that within Error.aspx I can't figure out how to get a reference to the exception. I tried this:
Dim oEx As Exception = Server.GetLastError()
But it returns Nothing. I also tried HttpContext.Current.Error() and HttpContext.Current.AllErrors and those don't work either.
In a custom error page running under IIS7 Integrated mode, how do I get a reference to the handled exception?
You need to intercept the error, either in Global.asax or a custom IHttpModule implementation as follows:
public class UnhandledExceptionHandlerModule : IHttpModule {
private HttpApplication application;
public void Init(HttpApplication application)
{
this.application = httpApplication;
this.application.Error += Application_Error;
}
public void Dispose()
{
application = null;
}
protected internal void Application_Error(object sender, EventArgs e)
{
application.Transfer("~/Error.aspx");
}
}
Then, in Error.aspx.cs:
protected void Page_Load(object sender, EventArgs e) {
Response.StatusCode = 500;
// Prevent IIS from discarding our response if
// <system.webServer>/<httpErrors> is configured.
Response.TrySkipIisCustomErrors = true;
// Send error in email
SendEmail(Server.GetLastError());
// Prevent ASP.NET from redirecting if
// <system.web>/<customErrors> is configured.
Server.ClearError();
}

Is it possible to execute a function at IIS for authentication before hits URLs?

Our applications are hosted at IIS as below hierarchy:
MainAppn1
---subAppn1
---subAppn2
---subAppn3
Is it possible to execute a function automatically at IIS to do authentication commonly for all sub applications whenever user hits url (for eg. http://server1/MainAppn1/subAppn1.aspx. Best answers would be greatly appreciated!.
You could implement Custom HTTP Module.
namespace AspNetWebForm
{
public class CustomHttpModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += Application_BeginRequest;
application.AuthenticateRequest += Application_AuthenticateRequest;
application.AuthorizeRequest += Application_AuthorizeRequest;
}
private void Application_BeginRequest(object sender, EventArgs e)
{
}
private void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
private void Application_AuthorizeRequest(object sender, EventArgs e)
{
}
public void Dispose()
{
}
}
}
web.config
Registering the HTTP Module in IIS 7.0 Integrated Mode.
<configuration>
<system.webServer>
<modules>
<add name="CustomHttpModule" type="AspNetWebForm.CustomHttpModule"/>
</modules>
</system.webServer>
</configuration>

Resources