i have an asp.net website where i need to use URL re-write so i have written an HTTP module and i have implemented it and it works correctly the only problem is when the page redirect to its corresponding address the images and the styles are not loaded.
here is the http module:
// Your BeginRequest event handler.
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
string URL = application.Request.Url.ToString();
//int pid = Convert.ToInt32(application.Request.QueryString["pid"]);
if ((URL.ToLower().Contains(".aspx"))
|| (URL.ToLower().Contains(".js"))
|| (URL.ToLower().Contains(".css"))
|| (URL.ToLower().Contains(".gif"))
|| (URL.ToLower().Contains(".png"))
|| (URL.ToLower().Contains(".jpeg"))
|| (URL.ToLower().Contains(".jpe"))
|| (URL.ToLower().Contains(".jpg"))
|| (URL.ToLower().Contains(".ashx")))
return;
else
{
string mname = URL.Substring(URL.LastIndexOf("/") + 1).ToString();
Merchand ms = merchantDB.GetMerchant(mname);
HttpContext context = application.Context;
if (ms != null)
{
string url = "~/pages/Merchant.aspx?mid=" + ms.MerchandID + "&catid=" + ms.MainCategory + "&subcatid=0";
context.RewritePath(VirtualPathUtility.ToAppRelative(url));
}
else
{
//("");
string url = "~/pages/default.aspx";
context.RewritePath(VirtualPathUtility.ToAppRelative(url));
}
}
}
when i open the page from it normal URL it opens fine, but when i use the url rewrite it open but with out images or styles.
when i open firebug i get an error that the css and the javascript are not found
To make rewrite work with IIS, do the following:
Register the httpmodule in web.config in the system.webserver tag:
<modules>
<add name="Rewrite" type="Rewrite"/>
</modules>
change this: context.RewritePath(VirtualPathUtility.ToAppRelative(url)); to this: context.RewritePath(url, false);
make your images runat server and put their path as ~/images/imagename
Related
I am wanting to redirect a page to a secure connection for an ASPX file.
Clients are asked to copy and paste a URL that looks like this foo.com.au into the browser.
I have this code below working on the code behind file but am wondering when it is deployed to production if this will update the URL to have www after the https://www as the URL provided to clients does not have www in it?
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (!Request.IsLocal && !Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl);
}
}
Rather than using Request.Url, use Request.Url.AbsoluteUri. In addition, you should not assume that the URL will be entered in lowercase. I would revise the code to be:
if (!Request.IsLocal && !Request.IsSecureConnection)
{
if (Request.Url.Scheme.Equals(Uri.UriSchemeHttp, StringComparison.InvariantCultureIgnoreCase))
{
string sNonSchemeUrl = Request.Url.AbsoluteUri.Substring(Uri.UriSchemeHttp.Length);
// Ensure www. is prepended if it is missing
if (!sNonSchemeUrl.StartsWith("www", StringComparison.InvariantCultureIgnoreCase)) {
sNonSchemeUrl = "www." + sNonSchemeUrl;
}
string redirectUrl = Uri.UriSchemeHttps + sNonSchemeUrl;
Response.Redirect(redirectUrl);
}
}
If you do this, all it will change is the schema. So, if the absoluteUri is
http://foo.com.au
it will be changed to
https://foo.com.au
One last note: when we have done this, we have never tried it in OnPreInit, we always perform this logic in Page_Load. I am not sure what, if any, ramifications there will be for redirecting at that portion of the page lifecycle, but if you run into issues, you could move it into Page_Load.
This was my final implementation to account for a request comes through for https://foo and not https://www.foo
if (!Request.IsLocal &&
!Request.Url.AbsoluteUri.StartsWith("https://www.", StringComparison.OrdinalIgnoreCase))
{
string translatedUrl;
string nonSchemeUrl = Request.Url.AbsoluteUri;
string stringToReplace = (Request.Url.Scheme == Uri.UriSchemeHttp ? Uri.UriSchemeHttp + "://" : Uri.UriSchemeHttps + "://");
nonSchemeUrl = nonSchemeUrl.Replace(stringToReplace, string.Empty);
if (!nonSchemeUrl.StartsWith("www", StringComparison.InvariantCultureIgnoreCase))nonSchemeUrl = "www." + nonSchemeUrl;
translatedUrl = Uri.UriSchemeHttps + "://" + nonSchemeUrl;
Response.Redirect(nonSchemeUrl);
}
I have this senario where my site www.skinb5.com should redirect to www.skinb5.com/au/
and www.skinb5.com/au should directly go to the www.skinb5.com/au and www.skinb5.com/us
should go to www.skinb5.com/us.
www.skinb5.com is a parent site which pretty much does nothin but to redirect. /au/ and /us/ are child sites sitting under it.
Please have a look at my Global.asax file in my parent site where the only redirect happens.
The problem is when i go www.skinb5.com/us/ it returns 200 which is good. But
www.skinb5.com/au/ it returns 302 to www.skinb5.com/au/. Though it doesn't go in an infinite loop, I am concerned why it returns 302.
you might want to test here at http://www.internetofficer.com/seo-tool/redirect-check/
My questions is, when I invoke www.skinb5.com/au/ directly, will the application_beginRequest in parentsite be invoked? Shouldn't it directly go to the child site? If so how does the 302 redirect happen.
protected void Application_BeginRequest(object sender, EventArgs e)
{
var redirectSite = "au";
HttpCookie languageCookie = HttpContext.Current.Request.Cookies.Get("Customer.SelectLanguageID");
if (languageCookie != null)
{
redirectSite = languageCookie.Value.Split('-')[1];
}
string rawUrl = HttpContext.Current.Request.RawUrl;
if (string.IsNullOrEmpty(rawUrl))
{
rawUrl = "/";
}
rawUrl = redirectSite + rawUrl;
bool useSsl = IsCurrentConnectionSecured();
var storeHost = GetStoreHost(useSsl);
if (storeHost.EndsWith("/"))
storeHost = storeHost.Substring(0, storeHost.Length - 1);
string url = storeHost + '/' + rawUrl;
url = url.ToLowerInvariant();
HttpContext.Current.Response.Redirect(url, true);
HttpContext.Current.Response.End();
}
A redirect tells the browser to load a different URL. The browser does this just as though the new URL was typed in the address bar. It is a request like any other.
So all requests and redirects will cause Application_BeginRequest() to fire.
If you don't want it to do anything on the redirected request, you'll need to test the target URL and decide if any action is to be taken.
IF this is my url http://localhost:55070/Server/1-Server
A link in that page will became
http://localhost:55070/Server/2-Instance_12
If I change the URL like this http://localhost:55070/Server/1-Server/
the link will be like this .http://localhost:55070/Server/1-Server/1-Instance_11
I want seconde type (http://localhost:55070/Server/1-Server/1-Instance_11/) always. If the user enters the URL like this http://localhost:55070/Server/1-Server it may cause some issues.
If this is the URL http://localhost:55070/Server/1-Server how can I append / to this http://localhost:55070/Server/1-Server/. So the links in next views are also append to it.
It is possible for user to remove the '/' and then also i need to add '/'.
This is the Razor for creating the URL.
You could adapt this solution Lower case URLs in ASP.NET MVC to redirect the user when the url does not end with a /
Or put it in a HttpModule like so:
public class UrlMessingModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += Application_BeginRequest;
}
public void Dispose() { }
protected void Application_BeginRequest(object sender, EventArgs e)
{
var application = (HttpApplication) sender;
var request = application.Request;
var response = application.Response;
var url = request.Url.AbsolutePath;
if (url.Length > 1 && !url.EndsWith("/"))
{
response.Clear();
response.Status = "301 Moved Permanently";
response.StatusCode = (int)HttpStatusCode.MovedPermanently;
response.AddHeader("Location", url + "/");
response.End();
}
}
}
On the button click I am calling a javascript function in the JS function I redirect to an aspx page and in the aspx page I want to redirect to another page (This part is not working).
response.redirect not re-directing, just posting back to current page. Any Idea why it is not working.
Here is my code :
Review.aspx:
<asp:Button ID="btnComplt" runat="server" Text="Complete" OnClientClick ="return compAsgn()" />
function compAsgn() {
if (window.confirm("Submit all images and complete the assignment?"))
window.location = "SendImages.aspx?insid=" + $("#IAssignmentId").val() + '&option=complete';
else
return false;
SendImages.aspx :
protected void Page_Load(object sender, EventArgs e)
{
assignmentId = Convert.ToInt32(Request.QueryString["insid"]);
string url = "Review.aspx?insid" + assignmentId.ToString() + "&viewOption=review";
string qstrVal = string.Empty;
qstrVal = Request.QueryString["option"].ToString().ToLower();
if (qstrVal != null && qstrVal == "complete")
{
using (ServiceClient client = new Proxies.ServiceRef.ServiceClient())
{
List<AssignmentInfo> ainfo = new List<AssignmentInfo>();
ainfo = client.GetAssignmentInfo(assignmentId);
if (ainfo.Count > 0)
{
if (ainfo[0].UploadedCount == 0)
{
// AfarSessionData class has a property called ProfileId, which is session variable.
if (AfarSessionData.ProfileId == "000000")
url = "Admin.aspx";
else
url = "HomePage.aspx";
}
}
}
}
Response.Redirect(url, false);
}
Note : When I debug I do see the control hitting the SendImages page but I see response.redirect not re-directing, just posting back to current page.
As far as I can tell, you're not doing anything to end the request. I'm not an ASP.NET guy, but I thought you should either:
Make the second argument true to effectively "hard abort" the request with an exception
Make the second argument false, but then call CompleteRequest to stop the rest of the pipeline
Some additional info related to John Skeets answer:
//ends request, no exception, calls Response.End() internally
Response.Redirect (url, true);
or
try
{
Response.Redirect (url, false);
}
catch(ThreadAbortException e)
{
//do whatever you need to
}
Here is some info on the issue:
PRB: ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer
I have a file upload in my site which is done using uploadify it uses a ashx page to upload file to database.It works fine in IE but in Mozilla the context.Session is getting null.I have also used IReadOnlySessionState to read session.
how can i get session in Mozilla like IE.
here is the ashx code i have done
public class Upload : IHttpHandler, IReadOnlySessionState
{
HttpContext context;
public void ProcessRequest(HttpContext context)
{
string UserID = context.Request["UserID"];
context.Response.ContentType = "text/plain";
context.Response.Expires = -1;
XmlDocument xDoc = new XmlDocument();
HttpPostedFile postedFile = context.Request.Files["Filedata"];
try
{
if (context.Session["User"] == null || context.Session["User"].ToString() == "")
{
context.Response.Write("SessionExpired");
context.Response.StatusCode = 200;
}
else
{
// does the uploading to database
}
}
}
}
In IE Context.Session["User"] always have the value but in Mozilla it is always null
You need to add sessionId to uploadify post params and restore ASP.NET_SessionId cookie on the server side on global.asax at OnBeginRequest. It is actually bug with flash and cookies.
I have created module for session and auth cookie restore, to get work flash and asp.net session, so i think it will be useful for your:
public class SwfUploadSupportModule : IHttpModule
{
public void Dispose()
{
// clean-up code here.
}
public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(OnBeginRequest);
}
private void OnBeginRequest(object sender, EventArgs e)
{
var httpApplication = (HttpApplication)sender;
/* we guess at this point session is not already retrieved by application so we recreate cookie with the session id... */
try
{
string session_param_name = "ASPSESSID";
string session_cookie_name = "ASP.NET_SessionId";
if (httpApplication.Request.Form[session_param_name] != null)
{
UpdateCookie(httpApplication, session_cookie_name, httpApplication.Request.Form[session_param_name]);
}
else if (httpApplication.Request.QueryString[session_param_name] != null)
{
UpdateCookie(httpApplication, session_cookie_name, httpApplication.Request.QueryString[session_param_name]);
}
}
catch
{
}
try
{
string auth_param_name = "AUTHID";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
if (httpApplication.Request.Form[auth_param_name] != null)
{
UpdateCookie(httpApplication, auth_cookie_name, httpApplication.Request.Form[auth_param_name]);
}
else if (httpApplication.Request.QueryString[auth_param_name] != null)
{
UpdateCookie(httpApplication, auth_cookie_name, httpApplication.Request.QueryString[auth_param_name]);
}
}
catch
{
}
}
private void UpdateCookie(HttpApplication application, string cookie_name, string cookie_value)
{
var httpApplication = (HttpApplication)application;
HttpCookie cookie = httpApplication.Request.Cookies.Get(cookie_name);
if (null == cookie)
{
cookie = new HttpCookie(cookie_name);
}
cookie.Value = cookie_value;
httpApplication.Request.Cookies.Set(cookie);
}
}
Also than you need register above module at web.config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="SwfUploadSupportModule" type="namespace.SwfUploadSupportModule, application name" />
</modules>
</system.webServer>
Context.Session is null.. because connection to HttpHandler has another Context.Session
(debug and try: Context.Session.SessionId in where is the fileInput is different from Context.Session.SessionId in Upload.ashx)!
I suggest a workaround: pass a reference to the elements you need in the second session ( in my sample i pass the original SessionId using sessionId variable)
....
var sessionId = "<%=Context.Session.SessionID%>";
var theString = "other param,if needed";
$(document).ready(function () {
$('#fileInput').uploadify({
'uploader': '<%=ResolveUrl("~/uploadify/uploadify.swf")%>',
'script': '<%=ResolveUrl("~/Upload.ashx")%>',
'scriptData': { 'sessionId': sessionId, 'foo': theString },
'cancelImg': '<%=ResolveUrl("~/uploadify/cancel.png")%>',
....
and use this items in .ashx file.
public void ProcessRequest(HttpContext context)
{
try
{
HttpPostedFile file = context.Request.Files["Filedata"];
string sessionId = context.Request["sessionId"].ToString();
....
If you need to share complex elements use Context.Application instead of Context.Session, using original SessionID: Context.Application["SharedElement"+SessionID]
It's likely to be something failing to be set by the server or sent back on the client.
Step back to a lower level - use a network diagnostic tool such as Fiddler or Wireshark to examine the traffic being sent to/from your server and compare the differences between IE and Firefox.
Look at the headers to ensure that cookies and form values are being sent back to the server as expected.
I have created a function to check session have expired and then pass that as a parameter in script-data of uploadify and in ashx file i check that parameter to see whether session exists or not.if it returns session have expired then upload will not take place.It worked for me. Did not find any issues using that. hope that solve my issue
I had a similar problem with an .ashx file. The solution was that the handler has to implement IReadOnlySessionState (for read-only access) or IRequiresSessionState (for read-write access). eg:
public class SwfUploadSupportModule : IHttpHandler, IRequiresSessionState { ... }
These Interfaces do not need any additional code but act as markers for the framework.
Hope that this helps.
Jonathan