I use url rewriting on my site (ASP.NET 4.0 / IIS6), instead of aspx I use html. Everything like described here: IIS 6 executing html as aspx . Problem is that when I have any real .html file (html file exists in the site folder) on the site it doesn't open in web-browser. Is it way to resolve this? Thanks!
You can use a custom httpmodule like this:
public class CheckRealHtmlFile : System.Web.IHttpModule
{
public void Dispose()
{
}
public void Init(System.Web.HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
System.Web.HttpApplication app = sender as System.Web.HttpApplication;
if (app != null)
{
System.Text.RegularExpressions.Regex rHtml = new System.Text.RegularExpressions.Regex(#"\.html$", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
if (rHtml.IsMatch(app.Context.Request.Url.AbsolutePath) && !System.IO.File.Exists(app.Context.Server.MapPath(app.Context.Request.Url.AbsolutePath)))
{
//Execute your html -> aspx logic
}
else
return;
}
else
return;
}
}
Related
This question already has answers here:
How can I programmatically stop or start a website in IIS (6.0 and 7.0) using MsBuild?
(3 answers)
Closed 7 years ago.
I am using the MVC5 for an web application. The web app runs in IIS7 or greater.
In the Global.asax on application_start, the number of licenses will be set:
protected void Application_Start()
{
try
{
MyApp.cNumberOfLicenses = COM.GetNumberOfLicenses();
}
catch(Exception e)
{
// log exception
// stop web site.
}
}
If any expection will be thrown in this context, the web site should shut down as you can do that in the IIS-Manager:
How can I stop the current web site in my Application_Start ?
You can do it with the help of "Microsoft.Web.Administration.dll"
using Microsoft.Web.Administration;
After adding the reference of "Microsoft.Web.Administration.dll" write below code in Global.asax
protected void Application_Start(object sender, EventArgs e)
{
try
{
MyApp.cNumberOfLicenses = COM.GetNumberOfLicenses();
}
catch (Exception e)
{
// get the web site name
var lWebSiteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
// log exception
// stop web site.
using (ServerManager smg = new ServerManager())
{
var site = smg.Sites.FirstOrDefault(s => s.Name == lWebSiteName);
if (site != null)
{
//stop the site...
site.Stop();
}
}
}
}
I will go not with stop it, but to show some message if you do not have license.
This is an example, and an idea.
You can use this code on global.asax where if you do not have licenses the moment you start, you open a flag, and after that you do not allow any page to show, and you send a page that you can keep on an html file.
private static bool fGotLicense = true;
protected void Application_Start()
{
try
{
MyApp.cNumberOfLicenses = COM.GetNumberOfLicenses();
}
catch(Exception e)
{
// log exception
// stop web site.
fGotLicense = false;
}
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
// if not have license - let show some infos
if (!fGotLicens)
{
// the file we look now is the app_offline_alt.htm
string cOffLineFile = HttpRuntime.AppDomainAppPath + "app_offline_alt.htm";
// if exist on root
if (System.IO.File.Exists(cOffLineFile))
{
using (var fp = System.IO.File.OpenText(cOffLineFile))
{
// read it and send it to the browser
app.Response.Write(fp.ReadToEnd());
fp.Close();
}
}
// and stop the rest of processing
app.Response.End();
return;
}
}
You can have a file named app_offline.htm with content say This website is offline now in web server and copy that to root directoy of website you want for any event.
It will directly show that message, but yes, App pool will be still ON, when you need to start , you just need to rename that to something else.
Currently my product page URL is like
http://www.localhost:80/products/default.aspx?code=productCode
I want to access product page with
http://www.localhost:80/productCode
I have used HTTP module for this.
public class UrlRewritingModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
context.AuthorizeRequest += new EventHandler(context_AuthorizeRequest);
}
void context_AuthorizeRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
if (some condition)
{
context.RewritePath(url);
}
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
//We set back the original url on browser
HttpContext context = ((HttpApplication)sender).Context;
if (context.Items["originalUrl"] != null)
{
context.RewritePath((string)context.Items["originalUrl"]);
}
}
}
I have register it in web.config and it is working fine. But when I deploy it in IIS that session and application variables are not throwing null referent Exceptions.
Can anyone help me?
Edit: Do it require extra code to access session/ Application variable for rewritten URLs
?
Have you tried using HTTPContext.Current?
I was able to solve issue (accessing session and application variables in subsequent pages rewritten by custom handler) by adding runAllManagedModulesForAllRequests="true" attribute in modules in web.config.
How we can add language name in URL by using Routing?
my site runs on http://localhost:41213/default.aspx URL successfully but this site in multilingual and my client wants run this site according to language like he wants http://localhost:41213/en/default.aspx instead of http://localhost:41213/default.aspx URL.
So my problem is that how to add en,es,hi,etc in URL and how to read this? default.aspx page is on root directory and it is home page.
Use this code in global.asax
public static void RegisterRoutes(System.Web.Routing.RouteCollection routes)
{
routes.Add(new System.Web.Routing.Route("{language}/{*page}", new CustomRouteHandler()));
}
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(System.Web.Routing.RouteTable.Routes);
}
void Application_BeginRequest(object sender, EventArgs e)
{
string URL = HttpContext.Current.Request.Url.PathAndQuery;
string language = TemplateControlExtension.Language;
if (URL.ToLower() == "/default.aspx")
{
HttpContext.Current.Response.Redirect("/" + language + URL);
}
}
make a router handler class like this...
public class CustomRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string language = TemplateControlExtension.GetString(null, requestContext.RouteData.Values["language"]).ToLower();
string page = TemplateControlExtension.GetString(null, requestContext.RouteData.Values["page"]).ToLower();
if (string.IsNullOrEmpty(page))
{
HttpContext.Current.Response.Redirect("/" + language + "/default.aspx");
}
string VirtualPath = "~/" + page;
if (language != null)
{
if (!VIPCultureInfo.CheckExistCulture(language))
{
HttpContext.Current.Response.Redirect("/" + SiteSettingManager.DefaultCultureLaunguage + "/default.aspx");
}
TemplateControlExtension.Language = language;
}
try
{
if (VirtualPath.Contains(".ashx"))
{
return (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(IHttpHandler));
}
return BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(Page)) as IHttpHandler;
}
catch
{
return null;
}
}
}
By using this i hope your requirement has fulfill.....
Probably the best way to do this is to have an initial page where he chooses the language he wants. Then the site loads a cookie to his browser indicating his language preference. In subsequent visits, your site reads the cookie and automatically takes him to his language preference.
I have two production websites that have similar content. One of these websites needs to be indexed by search engines and the other shouldn't. Is there a way of adding content to the response given to the client using the HttpModule?
In my case, I need the HttpModule to add to the response sent to the when the module is active on that particular web.
You'd probably want to handle the PreRequestHandlerExecute event of the application as it is run just before the IHttpHandler processes the page itself:
public class NoIndexHttpModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += AttachNoIndexMeta;
}
private void AttachNoIndexMeta(object sender, EventArgs e)
{
var page = HttpContext.Current.CurrentHandler as Page;
if (page != null && page.Header != null)
{
page.Header.Controls.Add(new LiteralControl("<meta name=\"robots\" value=\"noindex, follow\" />"));
}
}
}
The other way of doing it, is to create your own Stream implementation and apply it through Response.Filters, but that's certainly trickier.
When should I enforce SSL for secure pages in an ASP.NET page life-cycle?
I mean should I do it inside page_load? or OnInit? or some other function?
I am using the following code to enforce SSL for certain pages, but where should I put this code? Earlier I placed it inside OnInit function, but that did not work well with ASP.NET wizards. Do I need to check whether it's postback or not first?
If postback drops https, shouldn't my code enforce it? If postback does not drop https, shouldn't my code stop redirecting and move to the next step of the wizard? It seems like it keeps redirecting.
if (!HttpContext.Current.Request.IsSecureConnection) {
HttpContext.Current.Response.Redirect(SiteNavigation.ResolveAbsoluteUrl(true, HttpContext.Current.Request.Url.PathAndQuery));
}
You have basically two options.
If you want all authenticated pages to run under SSL, you can set the requireSSL="true" attribute on forms authentication. Just make sure your login page is also running on HTTPS.
You can also set this on a page-by-page basis. I found this works well in a "page base" class that inherits from System.Web.UI.Page, and that all your pages inherit from (instead of System.Web.UI.Page).
public class PageBase : System.Web.UI.Page
{
public bool RequiresSSL {get; set;}
string currentPage = Request.Url.ToString();
public PageBase()
{
Init += new EventHandler(PageBase_Init);
}
void PageBase_Init(object sender, EventArgs e)
{
if ((RequiresSSL) && (WebConfigurationManager.AppSettings["SSLavailable"] == "true"))
{
if (currentPage.ToLower().StartsWith("http://"))
{
redirectTo = "https://" + currentPage.Substring(7);
Response.Redirect(redirectTo);
}
}
else
{
if (currentPage.ToLower().StartsWith("https://"))
{
redirectTo = "http://" + currentPage.Substring(8);
Response.Redirect(redirectTo);
}
}
}
}
The AppSettings value of SSLavailable allows you to switch the whole mechanism off when you're running in test mode without SSL.
For pages that need to run in SSL mode, all they need to do is set RequiresSSL:
public partial class ChangePassword : PageBase
{
public ChangePassword()
{
PreInit += new EventHandler(ChangePassword_PreInit);
}
void ChangePassword_PreInit(object sender, EventArgs e)
{
RequiresSSL = true;
}
}
It works, very smoothly, and any other pages they go to after the secure page will automatically switch back to HTTP protocol.
I usually do this in the OnPreLoad event to force SSL:
protected override void OnPreLoad(EventArgs e)
{
base.OnPreLoad(e);
String qs;
qs = Request.QueryString;
//// Force the page to be opened under SSL
if (!Request.IsSecureConnection)
{
if (qs != "")
{
qs = "?" + qs;
}
Response.Redirect("https://" +
Request.ServerVariables["SERVER_NAME"].ToString() +
Request.ServerVariables["PATH_INFO"].ToString() + qs);
}
}
If you want to force SSL for all pages, it may be a good fit for an HttpModule. I have come up with the following:
using System;
using System.Web;
namespace CustomHttpModules
{
public class EnforceSSLModule : IHttpModule
{
public void Init(HttpApplication httpApp)
{
httpApp.PreRequestHandlerExecute += this.OnPreRequestHandlerExecute;
}
public void Dispose()
{
}
public void OnPreRequestHandlerExecute(object o, EventArgs e)
{
using (HttpApplication httpApp = (HttpApplication)o)
{
if (HttpContext.Current != null)
{
HttpContext ctx = HttpContext.Current;
String qs;
qs = ctx.Request.QueryString;
//// Force the page to be opened under SSL
if (ctx.Request.IsSecureConnection)
{
if (qs != "")
qs = "?" + qs;
ctx.Response.Redirect("https://" +
ctx.Request.ServerVariables["SERVER_NAME"].ToString() +
ctx.Request.ServerVariables["PATH_INFO"].ToString() + qs);
}
}
}
}
}
}
To use the HttpModule in IIS5.1 or IIS6, drop the compiled assembly for the HttpModule in your site's bin folder and add the following to your web.config's HttpModules section:
<add type="CustomHttpModules.EnforceSSLModule, dllname" name="EnforceSSLModule" />
(where dllname is the name of your assembly file without the extension)