Of course that Request.UserHostAddress way is great, however in Application_Start() the Request object isn't exists yet.
I want to first guess the location of user by his/her IP - just one time - as he/she enters the web site, and set the default locale for him/her. Then I'll manipulate it some where else.
I think that there must be an event to be overridden in Global.asax which Request exists in it, However I can't find that event...
Indeed any alternate trick will be appreciated...
Update:
In fact, I'm developing a multilingual web site and I use MaxMind GeoIP to get the country of users by their IP. So, I want to find a way in order that when a user enters the site (only and only the first request) I retrieve his/her country and store it in Session or a global variable.
I know that I can achieve my goal any where else by Request.UserHostAddress and I have not any problem with it - just one line overhead for each request isn't an issue at all for this small app.
However I wonder if it is possible to set that global variable, only and only once...!?!
Application_Start() is not right event, in which you can do this. It will not run for every request from your user, it does some basic initialization of asp.net application.
Better solution is to user, for example
protected void Application_BeginRequest(){}
which runs on beginning of request from client.
About earliest event, in which both request and session will be available... Seems like it is
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (System.Web.HttpContext.Current.Session != null)
{
if (Session["locale"] != null)
{
//already set variable.
}
else
{
//set some variable
Session["locale"] = "code";
}
}
}
But what exactly do you want to you mean by "setting locale based on IP"? Can you clarify this task? 'Cause in general, for each request execution this "locale" information must be set.
You should do this like this
public void Init(HttpApplication context)
{
context.BeginRequest += (Application_BeginRequest);
}
private void Application_BeginRequest(object source, EventArgs e)
{
var context = ((HttpApplication) source).Context;
var ipAddress = context.Request.UserHostAddress;
}
It may be solved by using GlobalFilterCollection. You can override the method OnActionExecuting and add the necessary logic. This article: ASP.NET MVC 4 Custom Action Filters may help.
Related
I have a Sharepoint 2013 application and need to prevent users from login from differents places at same time.
Searching for a good solution I found out that giving a new session token each time the user login is a good solution. Also I will have to expires all older tokens from that user.
How can I do this using c#.Net ?
Try to do it like in normal ASP.NET app, the only difference would be to use session start from HttpModule, not from global.asax.
In your case do following:
Create custom IHttpModule
public class CustomSessionHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
IHttpModule httpModule = context.Modules.Get("Session");
var sessionModule = httpModule as SessionStateModule;
if (sessionModule != null)
{
sessionModule.Start += OnSessionStart;
}
}
public void Dispose()
{
}
private void OnSessionStart(object sender, EventArgs e)
{
//Check if user has active session( in your storage) if yes then invalidate it or block new request
}
}
Add module to the web.config in the farm with SPWebConfigModification to
configuration/system.webServer/modules view feature (as a PoC do it manually)
Ensure that session is enabled in the web.config (as far I remember this is required)
I've tried a lot of solutions to this. I've tried to deal with Sessions, Cookies without success.
My solution was to use some way of verification like IP for instance.
After check the IP (if the user IP changed) the program redirects the user to the following page:
[sharepointsite]/_layouts/closeconnection.aspx?loginasanotheruser=true
This page is from olders versions of Sharepoint and is hidden in the 2013 version.
It forces the user to log in again.
Here is some code example:
if(currentIP != lastIP)
{
updateIP(currentIP);
Response.Write("<sharepointsite>/_layouts/closeconnection.aspx?loginasanotheruser=true");
}
I know this is not the best solution, but was the only one that worked for me.
I am developing a SQL Server based async browser chat with ASP.NET MVC in C#. My project consists of a web project, a winforms application and a database of course. In my database, I have a table called User with a DateTime property named LastLogin and another boolean property named isOnline. I want to set isOnline to false, if (LastLogin + 15sec =< DateTime.Now), so 15seconds is the timeout. What is the best solution to solve this problem in your opinion?
Do you have suggestions for a better title?
First off, checkout something like the SignalR source to see how they're doing it. Second, I'd look into doing it via Session && Logout.
In your Global.asax
void Session_End(Object sender, EventArgs E) {
// update the database with "offline"
}
In your logout code
protected void LogOut_Click(object sender, EventArgs e)
{
// logout
// update database with "offline"
// redirect to public page of your choosing.
}
I am trying to detect incoming url in asp.net page and making some decision on the base of that url But I am facing some problem here is my c# code the detect the url and also condtions
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
String url = Request.ServerVariables["HTTP_REFERER"];
if (url != "http://172.17.0.221:84/CP.aspx")
{
Response.Redirect("http://a.sml.com.pk");
}
else
{
Response.Redirect("http://172.17.0.221:85/MilkSale.aspx");
}
}
}
</script>
But When I call the page from http://172.17.0.221:84/CP.aspx then it gives this error:
This webpage has a redirect loop.
The webpage at http://172.17.0.221:85/MilkSale.aspx has resulted in too many redirects. Clearing your cookies for this site or allowing third-party cookies may fix the problem. If not, it is possibly a server configuration issue and not a problem with your computer.
Can any one tell me what may the error in this code?
If your script statement is also on the MilkSale.aspx page, then it will fire every time the page is hit; in effect, it will redirect to itself forever (or, in this instance, until asp.net detects that it is requesting the same page over and over again).
To begin with:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
String url = Request.ServerVariables["HTTP_REFERER"];
if(!String.IsNullOrEmpty(url))
{
if (!url.ToUpper().Contains("CP.ASPX"))
{
Response.Redirect("http://a.sml.com.pk");
}
else if (!url.ToUpper().Contains("MILKSALE.ASPX") && !url.ToUpper().Contains("CP.ASPX"))
{
Response.Redirect("http://172.17.0.221:85/MilkSale.aspx");
}
}
}
}
Then this will fix the first issue. However, you then have to consider some other issues with your code;
You are doing case insensitive string matching.
You have IP addresses hard coded in your urls
1) is pretty easy to use; you can use String.Compare(url, referrer, StringComparison.InvariantCultureIgnoreCase) for example. In my code, I have used .ToUpper() but this is still fraught with issues (but makes for a compact example)
2) Is more difficult; you should really disassociate your redirect mechanism from the root url, or else you'll have to change your code everytime you change site. Either use the property HttpContext.Current.Request.Url.PathAndQuery or, preferably, look at URL rewriting.
I am currently using session to hold the user ID at my web application. And i read a lot about sessions is evil, so my plans is to find another solution.
So my next step is to use encrypted cookie.
Something like:
userInformation: ENCRYPT(UserID,subdomain,someComputerUniqueValue,hashvalueOftheString)
each user has their own subdomain, so the UserID and Subdomain must match.
But. Now at almost every page i call the session value to get the userID.
I want to change this to some kind of variable, but what kind of variable?!
I am now setting the session value inside a httpmodule. in the
public void Application_PreBeginRequest
Is it possible to create a variable within application_prebeginRequest and read it somewhere else during the creation of the page. for example in the masterpage, och the contentpage. or the classes that is used at that specific page.
WHen the page is created and sent to the client, the variable should die.
What kind of variable am i looking for? is it global variable? if not, what is global variable?
Thanks for reading!
Mattias R.
Edit:
This cookie is not for authentication. I want to save the ID of the user connected to the subdomain, so i dont have to run the "SELECT ID from account where subdomain='somethin'" query each time a page is visited.
You can store what you need inside the HttpContext.Current.Items. Items put inside that will live only during the current web request and will be available globally in your web application.
// Global.asax
void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items["hello"] = DateTime.Now;
}
// Default.aspx
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = HttpContext.Current.Items["hello"].ToString();
}
}
By the way, at Application_BeginRequest event, the Session object isn't available.
For more information about HttpContext.Current.Items, look at https://web.archive.org/web/20201202215202/https://www.4guysfromrolla.com/articles/060904-1.aspx.
Once the user is authenticated, why don't you log them in with FormsAuthentication.SetAuthCookie?
You can then retrieve the currently logged in user using HttpContext.Current.User.Identity.Name.
Session is not "evil" Session is stored on the server, and for small amounts of data such as what you suggest, it scales very well.
I have web application which supports globalization. So i need to provide user a choice to select a language one he/she logs in. Now the problem is where do i have to make changes to set the user's preferred language.
Use the ASP.NET profile feature to declare the user's preferred language as a profile property. See Tutoriel
(Note that this is a rephrasing of #Ikaso's answer, so s/he should answer and get credits)
Ok I got the solution:
I tried the following changes in the global.asax file
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
if (Session["userCultureInfo"] != null)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Session["userCultureInfo"].ToString());
}
}
Alternatively to the solution you got, you can have your own HTTP module and set the culture there by passing it through the URL for example. But you need to do that in the module before the page lifecycle starts.