I have written an HTTPModule for the redirection purpose and installed in GAC and referenced in root web.config file. It is working for Team sites very well.
I am using PreRequestHandlerExecute to see the request is page or not and calling
public void Init(HttpApplication context)
{
this.app = context;
this.app.PreRequestHandlerExecute += new EventHandler(Application_PreRequestHandlerExecute);
}
void Application_PreRequestHandlerExecute(object source, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null)
{
page.PreInit += new EventHandler(Perform_Redirection);
}
}
and in the Perform_Redirection method I am doing the redirection stuff.
void Perform_Redirection(object source, EventArgs e)
{
//logic goes here for redirection
}
The above code working fine for Teamsites but not for Publishing sites. The Page.PreInit is not firing for publishing sites.
Please help me to solve this problem!
I am using PreRequestHandlerExecute, because I need session object and other details otherwise I would have used BeginRequest.
I solved it by moving the redirection code into the PreRequestHandlerExecute event handler
Related
I am working on a Hobby application in Blazor Server. The first stage in this application involves directing the user to an external site to have them authorize my app (OAuth2) to access their information from the external site. Part of this process involves a return authorization code. I have a Webforms version of this application where the Start page redirects the user to a URL and then a callback page completes the task of capturing a token. I cannot figure out how to capture the "Code" from the response in the Callback from the external server. Any help?
Start Page:
public void Btn_UM_CreateNew_click(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(TestNew));
}
private async Task TestNew()
{
using (var eveAuth = new EveAuth())
{
var url = await eveAuth.EveAuthGet();
Response.Redirect(url);
}
}
Callback page (where I extract the "Code" value:
protected async void Page_Load(object sender, EventArgs e)
{
var resp = Request["code"];
using (EveAuth eveCallback = new EveAuth())
{
await eveCallback.EveTokenGet(resp);
}
Is the "Code" passed to the Callback page via a query string?
If so you can refer to the below article
https://chrissainty.com/working-with-query-strings-in-blazor/
I'm in the process of upgrading a legacy app that I inherited from MVC3 to MVC5 and somehow I broke the HTTPContext.User object.
The app has a custom authentication mechanism that seems to be working correctly as it returns a proper User object to the rest of the pipeline. Specifically, in Global.asax.cs:
protected void Application_BeginRequest(object sender, EventArgs args)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.GetType().FullName.Equals("Citation.AMS.Users.UserContext", StringComparison.OrdinalIgnoreCase))
{
try
{
using (IAuditor auditor = CoreFactory.AuditorCreate())
{
auditor.WriteAudit(HttpContext.Current, "Compliance");
}
}
catch (Exception ex)
{
using (ILogger log = CoreFactory.LoggerCreate())
{
log.WriteFatalError("Exception in Application_BeginRequest::Audit.", ex);
}
}
The check for HTTPContext.Current.User returns the correct object above. But by the very next method call:
protected void Application_AcquireRequestState(object sender, EventArgs args)
{
CultureInfo ci = null;
HttpCookie cookie = Request.Cookies[CookieHelper.CookieName];
if (cookie != null && !string.IsNullOrWhiteSpace(cookie.Values[CookieHelper.CultureName]))
{
ci = new CultureInfo(cookie.Values[CookieHelper.CultureName]);
}
else
{
The object is converted then to an RolePrincipal instead of the correct User type.
There must be some processing done between those two method calls in the pipeline but I can't figure out what's happening between them that would change the user object.
In the original code base, this doesn't happen. I've also created a new branch based on the MVC3 branch and upgraded all the nuget packages and updated the web.config files as I found issues and that seems to work better (don't want to go that route because my other branch has a lot of other changes that would be challenging to replicate.)
Can someone tell me what I'm missing or how to find out why the object is changing between these method calls?
Found it, it was custom javascript that was redirecting my controllers.
I created an asp.net mvc project. In this project I want some code always running. I publish my code on a web hosting service. For first time I start the application by sending an http request to my domain and I expect the application to be always kept alive and never shut down. But this does not happen.
Even I saw some solutions that say if I ping my domain sometimes in my code prevent the application from shutting down. But this solution extend application life cycle to about 24 hours (not always!!!)
Here is my code:
public class Main
{
public static void main()
{
while (true)
{
try
{
// some codes
}catch(Exception exp)
{
// log the exception message, (but any exception hasn't occurred till now
}
}
}
}
Global.asax: (by using this code, the application shutdown shortly, in this way I use a dummy controller)
public class MvcApplication : System.Web.HttpApplication
{
static Thread keepAliveThread = new Thread(KeepAlive);
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
keepAliveThread.Start();
Main.main();
}
protected void Application_End()
{
keepAliveThread.Abort();
}
static void KeepAlive()
{
while (true)
{
WebRequest req = WebRequest.Create("http://mydomain/Home/Index");
req.GetResponse();
try
{
Thread.Sleep(60000);
}
catch (ThreadAbortException)
{
break;
}
}
}
}
Global.asax: (by using this code, application stay running about 24 hours. in this way I don't use any controller)
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
Main.main();
Timer timer = new Timer(new TimerCallback(refreshSession));
timer.Change(0, 5 * 60 * 1000); // 5 min
}
static void refreshSession(object state)
{
Unirest.get("http://mydomain/");
}
}
Is there any better solution for my purpose? If yes please give me a sample code.
Normally that's called scheduled/background jobs. You can use "scheduled" for googling. Most hosting provide some means to do it form the control panel. On azure for example you could use "webjobs".
Note that there are some well-known solutions for background jobs, like hangfire for example. Don't re-invent the wheel unless you really have to.
I've searched a lot but didn't find any solution. So here is my case:
I have database model UrlRedirect
public class UrlRedirect : AuditInfo
{
[Key]
public int Id { get; set; }
public string OldUrl { get; set; }
public string NewUrl { get; set; }
}
As you may assume I am trying to save URL mapping between OldUrl and NewUrl.
I want to internally change the OldUrl path of the request to the NewUrl and then run all defined routes as they will run if the user is opening NewUrl directly.
The redirect should be server side URL rewrite and user should see the old URL in their browser
In Global.asax you have some events that are executed in the web application context. (for sample: Start_Application, End_Application, etc).
In your case, you could use the BeginRequest event, where every request made to your web application is executed. In this event you could check the URL and try to redirect it using the default of htpp protocols, such as 301 Moved Permanently status code. For sample, in the Global.asax file, add the code bellow:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
// get the current url
string currentUrl = HttpContext.Current.Request.Url.ToString().ToLower();
// here, you could create a method to get the UrlRedirect object by the OldUrl.
var urlRedirect = GetUrlRedirect(currentUrl);
// check if the urlRedirect object was found in dataBase or any where you save it
if (urlRedirect != null)
{
// redirect to new URL.
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", urlRedirect.NewUrl);
Response.End();
}
}
In the sample, GetUrlRedirect(string) method should check it in a database, xml file, cache, or anywhere you save the UrlRedirect objects.
To understand more about how asp.net core applications life cycles works, read this article.
If you really want to redirect within the server you may use one of the following:
HttpServerUtility.TransferRequest
HttpServerUtility.Transfer
HttpServerUtility.Execute
HttpContext.RewritePath
You can read more about these options, where a similar problem is posed here.
Consider the impact of your choice on the request serving performance. IMHO you should try your best to utilize MVC infrastructure of Routing, or just fall back to simple redirections (even permanent for speed) as [user:316799] wrote when you compute new urls in business layer or map from db.
This is my final solution that works like a charm. Thanks to #WeTTTT for the idea.
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
// ...
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
this.ApplyCustomUrlRedirects(new UowData(), HttpContext.Current);
}
private void ApplyCustomUrlRedirects(IUowData data, HttpContext context)
{
var currentUrl = context.Request.Path;
var url = data.UrlRedirects.All().FirstOrDefault(x => x.OldUrl == currentUrl);
if (url != null)
{
context.RewritePath(url.NewUrl);
}
}
}
I'm using the mini-profiler on my asp.net MVC 3 application. I've implemented the profiler using the mvc nuget package. Everything works ok for standard page requests i get profile information sql everything.
However ajax requests don't seem to display initially. Just to let me confirm the request are completed without error. I've debugged this and they complete they also return http 200 responses in fiddler.
There is no request by the mini profiler that accompanies the ajax request. When i then navigate to another page i.e. a standard page request all the ajax request that were made on the last page are now displayed.
This is my mini profiler configuration page in App_Start
public static class MiniProfilerPackage
{
public static void PreStart()
{
//Setup sql formatter
MiniProfiler.Settings.SqlFormatter = new OracleFormatter();
//Make sure the MiniProfiler handles BeginRequest and EndRequest
DynamicModuleUtility.RegisterModule(typeof(MiniProfilerStartupModule));
//Setup profiler for Controllers via a Global ActionFilter
GlobalFilters.Filters.Add(new ProfilingActionFilter());
//Settings
MiniProfiler.Settings.PopupShowTimeWithChildren = true;
MiniProfiler.Settings.PopupShowTrivial = false;
//Ignore glimpse details in miniprofiler
var ignored = MiniProfiler.Settings.IgnoredPaths.ToList();
ignored.Add("Glimpse.axd");
MiniProfiler.Settings.IgnoredPaths = ignored.ToArray();
}
public static void PostStart()
{
// Intercept ViewEngines to profile all partial views and regular views.
// If you prefer to insert your profiling blocks manually you can comment this out
var copy = ViewEngines.Engines.ToList();
ViewEngines.Engines.Clear();
foreach (var item in copy)
{
ViewEngines.Engines.Add(new ProfilingViewEngine(item));
}
}
}
public class MiniProfilerStartupModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, e) =>
{
var request = ((HttpApplication)sender).Request;
MiniProfiler.Start();
};
//Profiling abadened if user is not in the admin role
context.PostAuthorizeRequest += (sender, e) =>
{
if (!context.User.IsInRole("Admin"))
MiniProfiler.Stop(discardResults: true);
};
context.EndRequest += (sender, e) =>
{
MiniProfiler.Stop();
};
}
public void Dispose() { }
}
Is there some configuration that is required or potential issues I should be aware of?
In the end i figured out that the Miniprofiler JavaScript block that is added to the page must be below the pages jquery reference.
My JavaScript reference are all added at the end of the page for best practice performance reasons.
But I'd left the #MvcMiniProfiler.MiniProfiler.RenderIncludes() in the page header. Moving it below the jquery script ref at the bottom of the page fixed my problem.
Just found out that the same situation repeat if
$.ajaxSetup({
global: false
});