I have a permission check code snippet in each page in my application like below,
<%
int permission = Int32.Parse(Session["userpermission"].ToString());
if (permission != 1) {
Response.Redirect("Login.aspx");
}
%>
So if it is not equals 1, then it will redirect to Login Page, but now i need to add permission = 2 also into this condition in a specific page, where both permission levels 1 & 2 can enter, but I tried using OR operator "|" inside if condition like (permission != 1 | permission != 2), but then neither both permission levels can enter the page, Please suggest a solution.
It is not a good design practice to authorize a user. The future maintenance will be nightmare.
Ideally, you want to use Role based authorization.
If you cannot implement Role base authorization, you can at least use a BasePage, and inherit all xxx.aspx.cs from the BasePage.
public partial class Default : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
public class BasePage : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
int permission = Convert.ToInt32(Session["userpermission"] ?? "0");
if (permission == 1 || permission == 2)
{
// User is authorized, so allow access.
}
else
{
Response.Redirect("Login.aspx");
}
}
}
You can also use the logic like this. I personally do not like it because it is hard to read.
if (permission != 1 && permission != 2)
{
Response.Redirect("Login.aspx");
}
Checking whether the permission doesn't equal 1 or doesn't equal 2 will always be true.
After all, no possible number can equal both 1 and 2, so it will always be equal to one of them.
You want to check whether it is unequal to 1 and also unequal to 2.
Related
I am new to programming. In my web application, user will receive a popup alert when he attempts to access restricted page. After three unsuccessful attempts i want him to be logged-out(i.e redirect to logout page). My question is, how to capture each failed attempts.
My existing code for giving alerts,
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Convert.ToString(Session["StaffID"]) != "1" || Convert.ToString(Session["StaffID"]) == null || Convert.ToString(Session["StaffID"]) == "")
{
Response.Write("<script language='javascript'>window.alert('You are not allowed to view this page');window.location='Mainpage.aspx';</script>");
}
}
You can capture each failed attemped by using another session . Please check below code. I am test this in ASP.NET MVC. Session["StaffID"] is your condition check or any condition so use another session to count attempt. Hope it will help you.
public ActionResult OnInit()
{
base.OnInit(e);
var accessCount = Convert.ToInt16(Session["AccessCount"]);
if (Convert.ToString(Session["StaffID"]) != "1" || Convert.ToString(Session["StaffID"]) == null || Convert.ToString(Session["StaffID"]) == "")
{
//Response.Write("<script language='javascript'>window.alert('You are not allowed to view this page');window.location='Mainpage.aspx';</script>");
accessCount++;
if (accessCount <= 3)
{
Session["AccessCount"] = accessCount;
return Content("<script>alert('You are not allowed to view this page')</script>");
}
else
{
Session["AccessCount"] = 0;
return RedirectToAction("logout");
}
}
}
In Bills and Adjustments, an error message "Please upload invoice" needs to display if user tries to save without attaching/uploading a document.
I created a bool field, UsrFilesAttached, that does not persist. On Rowselected event, i get a count, set bool if 0 or not.
I tried updating AP.APRegister DAC to [PXUIRequired(typeof(Where>))]
I tried something else in the BLC but I can't find it now.
//in APInvoiceEntry
protected void APInvoice_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
var inv = (APInvoice)e.Row;
bool attachedFiles = PXNoteAttribute.GetFileNotes(cache, cache.Current).Length != 0;
cache.SetValueExt<APRegisterExt.usrFilesAttached>(inv, attachedFiles);
}
// in DAC AP.APRegister
[PXBool]
[PXUIField(DisplayName="UsrFilesAttached")]
[PXDefault]
[PXUIRequired(typeof(Where<usrFilesAttached, Equal<False>>))]
I expect that if UsrFilesAttached is false an error will appear. I am able to save record whether UsrFilesAttached is true or false. Also, how do I add a custom error message?
This morning, I had a different thought about how to tackle this and it worked. I started over with this and it works:
protected void APInvoice_Hold_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
var inv = (APInvoice)e.Row;
if (inv == null)
return;
bool attachedFiles = PXNoteAttribute.GetFileNotes(cache, cache.Current).Length != 0;
if (attachedFiles == false)
{
cache.RaiseExceptionHandling<APRegister.hold>(inv, null, new PXSetPropertyException("Please attach invoice", PXErrorLevel.Error));
inv.Hold = true;
}
}
It makes better sense to do the check when trying to release the hold anyway. It can probably be improved on, so please teach me if you know a cleaner way. :)
I have a strange problem I'm checking in my code behind the user if he is active or not with as simple if .. in my Page_Load method as you can see here
private TimeReport paramTR;
private ZevUser zevUser;
protected void Page_Load(object sender, EventArgs e)
{
ZevUser user = ZevUser.GetById(Int32.Parse(Session["SessionId"].ToString()));
if (user == null)
{
this.Response.Redirect("~/About.aspx");
}
this.getParameters();
if (!this.IsPostBack)
{
if (paramTR.ZevUser.Active == 0)
{
this.Response.Redirect("~/TimeReporting/TimeReportPanel.aspx");
}
this.bindData();
}
}
But when I make a go throw to this method I get allays nullreferenceexception why so ever .. but the private ZevUser variable is not null it's full..
I really don't have a clue why is this happing, it would be really cool if someone could explain me this why this is happening
Thanks for help and fast answer
You need to break your code down so you can debug it easier or add logging if you cannot debug this code locally.
Remember that when debugging something, the worse mistake you can make is to make assumptions. Start from the beginning and follow the process through. Don't assume that the problem is something and don't assume that the problem can't be something:
I've included a broken down, more readable version below. You can now add logging around this or easily add breakpoints:
private TimeReport paramTR;
private ZevUser zevUser;
protected void Page_Load(object sender, EventArgs e)
{
this.getParameters();
if (!this.IsPostBack)
{
if ((this.paramTR != null) &&
(this.paramTR.ZevUser != null) &&
(this.paramTR.ZevUser.Active == 0))
{
this.Response.Redirect("~/TimeReporting/TimeReportPanel.aspx");
}
this.bindData();
}
string sessionId = Session["SessionId"] as string;
if (sessionId != null)
{
int session = int32.Parse(sessionId);
ZevUser user = ZevUser.GetById(session);
if (user == null)
{
this.Response.Redirect("~/About.aspx");
}
}
}
Why are you passing the session id to ZevUser.GetById()? I would expect this to take a user id, or for the method to be called something like ZevUser.GetBySessionId(). At the moment it's quite confusing.
This line is causing the issue:
ZevUser user = ZevUser.GetById(Int32.Parse(Session["SessionId"].ToString()));
This is because Session["SessionId"] can be null, and is null in this case.
If you are looking to get the SessionId that is set by ASP.net, then use this.Session.SessionID (source).
If you are storing a value in Session["SessionId"] that you are trying to retrieve, then do a null-check first:
if (Session["SessionId"] != null) { ...
You should consider testing the SessionId variable before using it by doing something like that :
if (!string.IsNullOrEmpty(Session["SessionId"].ToString()))
ZevUser user = ZevUser.GetById(Int32.Parse(Session["SessionId"].ToString()));
The best way to debug your exception is to enable debug when the exception is thrown.
For this, go to Debug>>Exceptions
and then enable first four checkboxes (maybe) and then try debugging the project. You will be halted at the position from where the exception will be thrown.
I have an expiry date in my database and I would like to redirect a web page when the expiry date for that page has been reached.
How would I do this?
Thanks
You can do that using a cache for your pages. I'm obviously not familiar how you store the expire dates, but I'll presume you have [exp_date: url].
So:
protected void Application_Start(object sender, EventArgs e)
{
Dictionary<Datetime, string> pages = Read_from_database();
Context.Cache.Insert("ExpireCache", pages, new CacheDependency(m_strPath),
System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
CacheItemPriority.Default);
}
And in
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Request.Url.AbsolutePath == "page_expired.aspx")
{
return;
}
var cache = HttpContext.Current.Cache["ExpireCache"];
if (cache.ContainsKey(HttpContext.Current.Request.RawUrl) &&
cache[HttpContext.Current.Request.Url.AbsolutePath] < DateTime.Now)
{
HttpContext.Response.Current.Redirect("page_expired.aspx");
}
}
You can additionally add a SqlDbDependency to the Cache, so that it get updated when you modify the expire dates in the Database...
You could put a Trigger on you database.
That fires off after a certain time or action and then test the date to make sure it's not expired.
If it is a simple code block like this could do the job.
if (HttpContext.Current.Request.Url.ToString().ToLower().Contains(
"http://mySite.com"))
{
HttpContext.Current.Response.Status = "301 Moved Permanently";
HttpContext.Current.Response.AddHeader("Location",
Request.Url.ToString().ToLower().Replace(
"http://mySite.com",
"http://www.myNewSite.com"));
}
Hope it helps
You can use this code to permanently redirect. #phadaphunk solution redirect Uppercase letters to small letters.
string authority = Request.Url.Authority;
if (authority.IndexOf("www.") != 0)
{
Response.StatusCode = 301;
Response.RedirectPermanent("http://www." + authority + Request.Url.AbsolutePath, true);
}
Note that Response.RediectPermanent method is only available for .Net 4.0 I think, otherwise you should use Redirect()
i am developing a web for my final project,and im new to ASP.NET and this forum.
thx to all who help me.
the question is...
example i have 2 pages.
page1.aspx.cs (this page for receive variable from mikrokontroler via network module)
example mikrokontroler send a variable "status" = 1
protected void Page_Load(object sender, EventArgs e)
{
NameValueCollection POST = Request.Form;
int STATUS;
int responcode;
try
{
A = int.Parse(POST["status"]);
}
catch (Exception)
{
status = 0;
}
if (A == 1)
{
responcode = 200;
//when A = 1, i want to store A value to (buffer on something <-- this what i want to ask)).
so i can call the value anytime in page2.
}
else
{
responcode = 400;
}
Response.StatusCode = responcode;
}
}
}
page2.aspx
(in page 2 there is button and textbox)
protected void Button3_Click(object sender, EventArgs e)
{
/*when this button click,
i want to show A value from page1
*/
}
You have a lot of options to store the variable value:
session state: Session["status"]= A
application state: Application["status"] = A
asp net cache: using Cache.Add()
database: here i would store also the timestamps, to trace the historic status of the controller.
local XML file.
It all depends on the scope of the stored data: session data is local to the current user/session and will expire after a predefined timeout(def: 20mins), application will be global to all your users/sessions and will expire when you will restart the application (by iis, iisreset, recompiling...), cache is global and will expire based on the parameters of invocation, the database and xml are global and will maintain state.
In your case i would use database or application store, because the microcontroller and user live in different sessions and the app cache is not a suitable messaging mechanism while Xml introduces some problems on his own (eg: filesystem permissions, data replication...).
write:
Application["status"] = A;
read:
int A = 0;
bool result = int.TryParse(Application["status"],out A);
BTW: to parse the integer you can skip the try/catch part doing this:
int A = 0;
bool result = int.TryParse(POST["status"],out A);
in this case if unable to parse A will be equal to 0;
You can use Session
NameValueCollection POST = Request.Form;
int STATUS;
int responcode;
try
{
A = int.Parse(POST["status"]);
}
catch (Exception)
{
status = 0;
}
if (A == 1)
{
responcode = 200;
//when A = 1, i want to store A value to (buffer on something <-- this what i want to ask)).
Session["Avalie"] = A;
so i can call the value anytime in page2.
}
else
{
responcode = 400;
}
Response.StatusCode = responcode;
}
}
and then on page 2
protected void Button3_Click(object sender, EventArgs e)
{
/*when this button click,
i want to show A value from page1
*/
if(!String.IsNullOrEmpty( Session["Avalie"] ))
int Aval = int.Parse(Session["Avalie"]);
}
Use crosspagepostback to pass values from one page to another (introduced in asp.net 2.0)
One option is to assign the value to a static variable in the first page.
Refer to Static Classes and Static Class Members (C# Programming Guide)
Another option is to use state variables as session state variables or application variables.
Refer to ASP.NET Session State Overview and ASP.NET Application State Overview