referring functions of 1st cs page in 2nd cs page - c#

Can we define a function in one cs page and refer that function in another cs page so that the functions designed in the 2nd cs page is executed with the 1st cs page function?
such like..in 1st cs page
Iwebdriver driver;
driver=new firefoxdriver();
In the 2nd cs page, I have many functions included based on the above function, so how can I refer this as a function in 2nd cs page so that code simplicity will exists?

This is a very badly worded question but I can only assume that essentially what you are trying to achieve is to have the ability to call functions from one test in another test, or rather one class from another class.
This is basic C#.
Your code should be split out in a way that means this is easily achievable. So it means that your tests are totally seperate from your actual logic.
Using Page Objects is one way to go:
http://code.google.com/p/selenium/wiki/PageObjects
This would mean you have a page like:
public class LoginPage
{
public HomePage Login(string username, string password)
{
// do the login stuff
// return the home page
}
}
public class HomePage
{
// some logic related to what the user can see on the home page.
}
You'd call it in a test like:
var loginPage = new LoginPage();
HomePage homePage = loginPage.Login(username, password);
Since it's now seperated, you could call LoginPage.Login() from anywhere.
The key here, is to not bundle all your logic into the tests themselves. As in, don't copy/paste the login code to login to your website into each test. Store it, like the above. The tests should be the steps you take, the page objects should define how those steps are taken. This way you can achieve your goal.

Related

ASP.NET MVC form wizard prevent user skipping wizard step (Controller Action) using URL bar

I’m currently working on a very large form. I thought it would be a good idea to section the form by implementing a form wizard (multiple views/action results) to improve the user experience.
One requirement is that the user must complete a small eligibility test that ensures they meet the minimum requirements prior to starting the application wizard itself.
Having done nothing like this before I can only see one approach to this problem and that is using a flag e.g IsEligible in a session that determines if the user can access the form wizard view/s. Let’s say my controller has two ActionResults (Eligibility and WizardStepOne) that server separate views. For example:
Controller - Untested Code
public ActionResult Eligibility()
{
Return View();
}
[HttpPost]
public ActionResult Eligibility(EligibilityViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
Session["IsEligible"] = true;
return("Success");
}
public ActionResult WizardStepOne()
{
bool stuff = (bool)Session["stuff"];
if(IsEligible == null)
{
return("Eligibility");
}
return RedirectToAction("Eligibility");
}
In short if the user attempts access the first step of the wizard and the IsEligible flag hasn't been set by the Eligibility post action then the user get redirected back to the eligibility form.
I've also looked into action filters but couldn't make much sense of it. I'll also have to implement this functionality at a later stage to prevent users skipping between wizard steps using the url e.g skipping WizardStepOne and starting at WizardStepTwo.
Is there a better approach then one described above in this situation? I'd rather avoid using a session as restarting the form becomes problematic as it would require a restart button to abandon the session especially between wizard steps.
What you are mentioning sounds like you might make use of some simple state machine to define valid steps through your form. So, when user is at stage 3. for example, you will check if he came from step 2 or not. For each step for particular user and session > you can save some hash value in his session. That way they could make no use typing in url directly.

Get Page control in a Method triggered by AJAX call

I call a method in a separate Class file that needs to update a label.
[WebMethod] //needed for the AJAX call
public static void MyClick(int postid, int userid) //must be static
{
Page page = new Page();
//Page page = HttpContext.Current.Handler as Page //Pass the Page but don't work
MyClass.MyMethod(postid, userid, page);
}
The method MyClick() is called from an asp.aspx file (With MasterPage), to a separate MyClass.cs file.
I am not being able to get the Control (Label) with FindControl(). My guess is the "Page" is not being passed correctly. For what i've seen in debug, "page" comes with many exceptions.
((Label)page.FindControl("ContentPlaceHolder1_lbl)).Text = "foo";
This is the sequence:
1) User clicks sort of a "Like" dynamically-created LinkButton
2) There is a JS listener that on click changes to "Dislike" (example) and does an AJAX POST to aspx page method MyClick() with parameters (postid, userid).
3) MyClick() calls MyMethod(postid, userid) that is in MyClass.cs
4) MyMethod() does some SQL (was working) and updates the label (AJAX call not working since MyMethod() tries to set label to "foo").
You're not passing the current page, you're creating a new one:
Page page = new Page();
You could just pass a reference to the current page:
MyClass.MyMethod(postid, userid, this);
(Though in order to do that your page method shouldn't be static. In fact, in order to reference anything on the page instance that method shouldn't be static. See edit below)
However, in general it's best practice not to have other components rely on your page elements. Only the page's code should know/care about the UI elements it owns.
Instead of having the method set the value, have the method compute and return the value and then have the page set it. Something like this:
var result = MyClass.MyMethod(postid, userid);
myLabel.Text = result;
That way the external component isn't tightly coupled to this specific page, can be re-used by other pages, etc.
Edit: What you're trying to do physically won't work in the framework you're using. AJAX-invoked web methods are static for a reason. They don't maintain page state. So in the context of that web method there is no page and there is no label. The AJAX call is a simple service which accepts values and returns a response.
So even if you could update a label server-side, that's not going to do anything client-side. Your client-side code needs to update the markup in the browser. To do that, the AJAX call should simply respond with the new value and the JavaScript code should use that returned value to update the page. Something like this:
[WebMethod]
public static string MyClick(int postid, int userid)
{
return MyClass.MyMethod(postid, userid);
}
As in the earlier part of this answer, that external component should simply calculate and respond with the new value. It should not be coupled to the page. This web method should result in the client-side code receiving the updated value. Then, however you manage that client-side (you have no client-side code in the question), you would update the page markup with that resulting value.

MVC Display Authenticated User Information on Authenticated pages

I have an ASPX MVC 4 C# web application that has user forms authentication. Once the user logs in, I would like to display a Welcome [user] message on any authenticated page. I know that User.Identity.Name pulls the user name, but I want to grab info from an additional field which would require a custom query.
How do I go about displaying the Welcome message on all pages?
I made an attempt at using a Partial file, but that got me no where. This should be one of the easier things... to variably pass a string onto every page based off logged in user, but from my searching it is not.
I would normally provide some of my code but I'm not sure there is really much to show, more or less I need a pointer or good example in the right direction.
Much appreciated
To get additional fields on a user object you can use the following:
Membership.GetUser(UserName)
and stores the message in a viewbag which you can use on all you views.
You can store the information in Session, screw ViewBag. You can set the Session Propert in the Global.asax file. You should see and OnSessionStart method inside the Global.asax.
So you can say
protected void Session_OnStart()
{
//Whatever is defaulted here
System.Web.HttpContext.Current.Session["blah"] = "Your User Name"
}
and then in the Shared Layout folder _Layout which is the default "Master Page" if you wanna call it that. You can call it like this whereever you like
#String.Format("{0}",System.Web.HttpContext.Current.Session["blah"]);
Edit:
An easy way you can use session variables is to create a Session variable class.
namespace YourSession
{
public static class SessionProperties
{
public static UserAccount UserAccountx
{
get
{
return (UserAccount)HttpContext.Current.Session["UserAccount"];
}
set
{
HttpContext.Current.Session["UserAccount"] = value;
}
}
}
}
And then in your onStart() method you can say
YourSession.SessionProperties.UserAccountx = "Get User Account Method or w.e";
Then in your view it would be
#String.Format("{0}",YourSession.SessionProperties.UserAccountx);
Although C Sharper pointed out a potential solution, that at first I thought worked, I decided it wasn't the exact solution I was looking for. Reason being if I logged out and then back in as a new user in the same session, the session was not updating as the session was already loaded.
Here is what I did:
Layout Master File
<% if (Request.IsAuthenticated) { %>
<div class="welcome">Welcome, <%: Html.Action( "GetUserInfo", "Member" ) %></div>
<% } %>
GetUserInfo is an ActionResult within the Member Controller
Member Controller
public ActionResult GetUserInfo()
{
string userInfo = "";
using (EntityObject db = new EntityObject())
{
var account = db.table_name.FirstOrDefault(u => u.UserID == User.Identity.Name);
userInfo = account.UserDataToDisplay;
}
return Content(userInfo);
}
*I did change actual item names to be more generic for description purposes.
Upon doing this it worked exactly as I wanted. I have one method under one controller, and one line of code on the master page that upon a user being authenticated, displays the relevant information.
Simple and Easy. Just took a while to figure it out.
Well you can use Cookies instead, they work same as session just they do not overload the server side. you can make them go expire when desired as well

Bad practice to have a Response.Redirect within a class in ASP.NET?

Within my ASP.NET App I am using a Method to check user permissions to decide whether the user can view the page, or get redirected to the "Invalid Permissions" page.
Since adding this Permission Redirect on the Master Page would cause an infinite loop, I am forced to apply it to all pages. I do not want to have to copy this Method onto every page, so I would like to create a class within my Web App which holds this Method so I can use it globally across my app.
I have had no formal training, but my gut is telling me that it's bad practice to place a Response.Redirect or any "Web" functions in a class? Am I correct? And if so, is there a better way to go about this?
You can check the current url to make sure that it is not already the invalid permissions page before redirecting; therefore, you will only redirect when you are not already there.
if(!Request.RawUrl.Contains("Invalid Permissions Page"))
Response.Redirect("Invalid Permissions Page");
You can make a new class, let's call it myPageClass, that heritage from System.Web.UI.Page, then, include all the code you need in this class make all your code behind heritable from myPageClass.
public class myPageClass : System.Web.UI.Page
{
public void authorize()
{
// your auth code here
Response.Redirect("Invalid_Permissions_Page.aspx", false);
}
}
public partial class _Default : myPageClass
{
protected void Page_Load(object sender, EventArgs e)
{
// Your code here
}
}
In my opinion, you should not use Response.Redirect in the cases of the action of a button, for example, if it's going to take you to another page, you don't need to go to the server to do that, that's only to be made in the client.
First things first, your original question:
Bad practice to have a Response.Redirect within a class in ASP.NET?
Yes I believe this is a bad practice. It's safer to pass a delegate, then your 'AuthorizeRequest' method can call the delegate. Here is an example:
public static void AuthorizeRequest(Action<string> redirect)
{
if( /*whatever*/ )
redirect("/InvalidPermissions.htm");
}
protected void Page_Load(object sender, EventArgs e)
{
AuthorizeRequest(Response.Redirect);
}
Now the bigger problem... You do not want to do this!
Having each page assert authorization is a quick way to write security issues. Someone will forget or accidentally remove the assertion. ASP.NET has a multitude of ways to intercept and filter requests for this very purpose.
The easiest thing to do is to place this in event hooks in your Global.asax file. The HttpApplication object has several events that can be used for this purpose. Another option is to implement the IHttpModule interface. Either way, I would not write the code in each page.

Login check in each ASP page using session variables (without forms/windows) authentication?

I am developing a website (as opposed to web application(so no global file)). I do not want to use forms/windows authentication or cookies. So session[] variables is the option i chose.
question:
How to check each and every page in the application if that session[] variable exists?
Any global class where the checking function can be included and called everytime the page_load is executed?
Technically speaking, unless you're using the cookieless session state, session variables are made possible via cookies, so you're indirectly using them anyway ;)
Anyway, it's as simple as you stated. You can simply include some code to check the existence of a session variable in the page_load of each page:
if (Session["mySessionVar"] == null
|| Session["mySessionVar"] IS_NOT_VALID)
Response.Redirect("/path/to/login/form/");
The IS_NOT_VALID represents some logic test to verify that the data in the variable is indeed valid data.
To have a "global class," you'll need to create a new page class that inherits from Page and does the check in your new classes Page_Load method. The trick is that every page you want to have checking the session variable will need to derive from your new class rather than the Page class. Pages that don't need the check can inherit from Page as normal. For example, something like this:
public class MyPageClass : Page
{
protected override void OnLoad(EventArgs e)
{
// Check to see if the session is valid
// and redirect to login if not
if (Session["mySessionVar"] == null
|| Session["mySessionVar"] IS_NOT_VALID)
Response.Redirect("/path/to/login/form/");
base.OnLoad(e);
}
}
public partial class MyLoginRequiredPage : MyPageClass
{
.
.
.
}
If you have a separate master page for home/profile page(different from login), you can write code in master page page_load only, so you don't have to write code for valid user in each page.
Code:
if (Session["adminid"] == null || Session["adminid"].ToString() == "")
{
Response.Redirect("adminlogin.aspx");
}
Even you can also use global.asax file as waqas raja told.
Hope this helps.

Categories