I have a simple web form called default.aspx in the folder structure webroot/folder/
When I navigate to http://myapp/folder/?key=value the page returns fine and when I call
<%= Request.QueryString[0] %>
I get http://myapp/folder/?key=value rendered on the page. However if I call
<%= Request.QueryString["key"] %>
I get nothing, and when I call
<%= Request.QueryString[1] %>
I get Index was out of range. Must be non-negative and less than the size of the collection.
This seems like a very trivial problem but I can't figure out what's going on?!
So it turns out that behind the scenes Sitecore turns the querystring into
?page=the-requested-page.aspx?key=value
But the url in the browser looks as requested. Obviously sticking a second ? in the actual url makes everything after the second ? disappear
If you apply a breakpoint, and then hover over the QueryString in Visual Studio then you should be able to view all of the keys. Alternatively you can foreach over the collection and print out the key names to see if it's slightly different to what you're expecting.
If you're doing something that isn't really supposed to be under Sitecore control (although I have never found it to make working with the QueryString collection impossible), try adding your /folder/ to the ignoreUrl setting. Sitecore will get out of your hair, then ;-)
your query string should be in /default.aspx?key =value then you will be able to access using ["key"] param
you can use
Request.QueryString.Count();
and get the count of querystring modifiy code accordingly
Related
I have two ASPX pages; they use the same DLL and class, so the first line of each file looks like:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="CustomPage.aspx.cs" Inherits="CustomPageCode.CustomPage" %>
(maybe this is bad form to have two *.aspx pages sharing the same codebehind, but I don't want to have two separate classes with identical code)
I'm 'configuring' each page through a hidden field --
Page1.aspx has the line:
<asp:HiddenField ID="DepartmentName" value="DepartmentOne" runat="server" />
and Page2.aspx has the line:
<asp:HiddenField ID="DepartmentName" value="DepartmentTwo" runat="server" />
My CodeBehind reads DepartmentName.Value to do a bunch of codebehind things, like SQL queries, based on the value of the HiddenField specific to each department, and also Javascript reads that value to do department-specific things as well. I'm doing it this way to simplify configuring each page -- the way the page is configured is right there in the ASPX page and the same value is visible to both ASPX and Javascript.
However, if either page does a POST event -- now DepartmentName.Value ONLY returns the value from the page that did the POST for any page with the same codebehind. Page1.ASPX, even though the asp:HiddenField value in the source is still clearly "DepartmentOne", if Page2.ASPX did the POST, DepartmentName.Value will be "DepartmentTwo" regardless of which page is opened.
The funky thing is: if I open the same page in Chrome, Page One will still have Page Two's DepartmentName.Value, even if the POST event never occurred in Chrome; clearing the IE cache doesn't fix it either. This is definitely something happening on the server side, getting cached somewhere. An IIS reset resolves it.
Google has told me that ASP.NET caches a bunch of things from a POST event but doesn't exactly say how it's handled, or how to enable/disable it, or which of the many cache locations it is located in, and many examples look like I'd have to specifically tell it to start caching things in a persistent way. The closest thing I've found is ModelState.Clear(); in a !IsPostBack at the beginning of the Page_Load, but that doesn't resolve it, I'm not using MVC in my code as far as I know.
So, my question is, how do I force that the GET uses the hidden value in the source code, and not some cached value from an old POST event?
It's probably ViewState, but I'd have to see more of your code for this to be more than a wild guess. I do see this:
I don't want to have two separate classes with identical code)
Yep, that's a good thing. But it sounds like maybe you have too much code in the page class itself that should be moved to a separate utility class, where two separate pages can now share that same utility code. Alternatively, you want a single Department.aspx page that takes a URL argument, like this: /Department.aspx?deptid=Department1 or /Department.aspx?deptID=Department2
Then key off of the url argument, rather than a hidden field. If you don't like the ugly URL, you can use routing to get prettier URLs like this: /Departments/Department1 or /Departmennts/Department2
I discovered my problem:
After wrestling with ViewState, it turns out my problem wasn't hidden fields being cached, it was what was being done with the hidden fields.
At the beginning of my class, I have a variable:
public static Dictionary<string, string> ThisDictionary = new Dictionary<string, string>();
that my code uses ThisDictionary.Add() to add values from ASPX hidden fields to -- but I never declared ThisDictionary as 'new' in my actual function, so every time I added an element to the Dictionary of hidden fields, it was persistent across multiple pages using the same class.
So, when I load my values from what I think is the hidden field, the codebehind is reading the hidden field correctly, but when it takes action in C#, it is using the data in the Dictionary with a bunch of other pages' data in it, hence the appearance that hidden field values are being cached somewhere.
By adding a statement to declare it as a new Dictionary<string,string>() at the beginning of my Page_Load function, it now wipes the dictionary clean with each page load and now it's behaving how I would expect, containing only values from the hidden fields on the particular page.
(I acknowledge what I should probably do is have a separate class with these variables in it, rather than lumping it all into the main ASPX class that gets called when the page loads. Something for the next version)
I am trying to do registration for this site
Registration page is inside a popup page.
HTML Code:
<fieldset>
<label>Username:</label>
<input name="username" required="" type="text"/>
</fieldset>
When I try to find the element using below tried code, element is not getting find.
driver.FindElement(By.XPath(".//*[#id='load_form']/fieldset[1]/input")).SendKeys("Kal");
I have also tried this with using CssSelector, but facing the same issue.
driver.FindElement(By.CssSelector("div#load_box form#load_form input[name=username]")).SendKeys("kal");
When I execute above code, I have got an error like element not visible
Can anyone help me on this issue?
Try this below code using xpath locator
driver.FindElement(By.XPath("//input[#name='name']")).SendKeys("Kal");
Explanation of xpath:- Use name attribute of <input> tag.
Suggesstion:- Instead of using absolute xpath, use relative xpath.
Note:- Before reach to this web-element provide some few seconds of wait, so your driver may able to find the web-element. So, you will not get an error like element not visible
Use below xpath:
//*[#id='load_form']/fieldset[6]/input[#name='username']
that site has 2 forms with the id load_form so you're getting the first one which isn't visible since it's the login form. You want the second one which is the register form.
you can use a selector to grab one of the fields that exists on the registration page and then move up to it's parent form and get all descendants that are fieldsets to fill out.
Here is the xpath you can use to pass the text "Dev" into the field labelled with "Name".
driver.findElement(By.xpath("//div[#class='fancybox-overlay fancybox-overlay-fixed']//form[#id='load_form']/fieldset/input[#name='name']")).sendKeys("Dev");
Let me know if this answers your question.
The problem is that there are two username INPUT fields. The way I typically handle this is to find a parent of the element that I want that has an ID or something unique that will distinguish the two elements. In this case, you can use a simple CSS selector,
#load_box input[name='username']
Note the load_box ID that distinguishes the two INPUTs.
Ajax popup on way2automation site is a tricky one because if you look for the username field by name By.name("username"), you will end up with 2 elements - one for username from signup popup, one from singin popup. To avoid this you have to explicity mention the correct element. This can be done via the following code:
webDriver.get("http://way2automation.com/way2auto_jquery/index.php");
WebDriverWait wait = new WebDriverWait(webDriver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a[href='#login'"))).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".ajaxlogin input[name='username']"))).sendKeys("my_username");
As you can see in the code I am using class of the login popup - .ajaxlogin. I have used Java, but the concept is the same - you have to refer to the username element via css selector with popup class included: By.cssSelector(".ajaxlogin input[name='username']")
I am using a ajaxToolkit:CollapsiblePanelExtender inside a repeater in a aspx page.
Since I need to have a unique behaviorID, I am setting it in this way:
((CollapsiblePanelExtender)(e.Item.FindControl("ControlPanelExtender"))).BehaviorID =
"bhvControlExtenderPanel" + e.Item.ItemIndex.ToString();
Now in Javascript I have to collapse/expand all the created panels according to a certain logic, but I am struggling in performing a partial match using the find() function.
$find("bhvControlExtenderPanel0").collapsePanel();
works, but I have to do it for every Panel, and I don't know the exact number.
Basically I need the equivalent of:
$("[id$='bhvControlExtenderPanel']")
Any idea on how to do that?
Thanks in advance
Try to use Attribute Starts With selector:
$("[id^='bhvControlExtenderPanel']")
Or any viable workaround.
So, imagine a Master page that implements IFooMaster with a method ShowFancyMessagePopupTheBusinessCantLiveWithout(string message);
I am in a page that inherits this master page. Upon a checkbox being unchecekd, I want to show a message to the user that if they save it, they can't re-check the checkbox without some admin action.
I've been given feedback that I can't just use an alert('message'); in javascript because they want the consistent look of these messages.
Next, I tried to make an ajax call via PageMethods (as that's what everything else in this codebase uses) to show a message. My problem lies in this method being static.
[WebMethod]
public static void ShowSuperImportantMessage()
{
if(!checkboxICareAbout.Checked)
((IFooMaster)Master).ShowFancyMessagePopupTheBusinessCantLiveWithout("If you uncheck that thing, you can't recheck it.");
}
Since ShowSuperImportantMessage() is static, I can't access Master from within.
The method on the master page looks more or less like this:
public void ShowFancyMessagePopupTheBusinessCantLiveWithout(string message)
{
lblGenericMessage.Text = message;
btnGenericMessageOK.Focus();
upGenericMessage.Update();
mpeGenericMessage.Show();
}
mpeGenericMessage is an ajaxtoolkit:ModalPopupExtender.
upGenericMessage is an update panel.
The other 2 are obvious.
Any ideas? Can I do some jQuery kung-fu to show that stuff? I tried, but the solution complained that the controls I tried to refer to by ClientID didn't resolve since they were on the Master page.
quick edit: Before anyone tells me the architecture is a problem, or I shouldn't have put such a thing on a master page, or w/e...
I know the situation is not ideal, but I this is inherited code, and I can't drop it all and rewrite half of their web stack.
Try something like this (untested):
((IFooMaster) ((Page)HttpContext.Current.Handler).Master)
It appears this doesn't work - Master isn't hooked up when the PageMethod is called (makes sense).
So, instead, create an empty page using the same master page. Have that page accept either a POST or GET with whatever parameters you need to pass to your master-page method. Have the Page_Load extract the parameters and call the method. It should then use Response.Write to return a result (and remember to change the Content-Type). Have your client-side code call the page and get the result.
Did you try something like window.top before the ClientID?
Per comments
You don't need to hardcode ClientID. Since your js is in page, try something along the following lines....
window.top.document.getElementById( "<%= yourelement.ClientID %>" ).Whatever();
Sorry to take so long to respond/answer.
I'm not proud of this at all, mind you, but the eventual solution was to hardcode the client IDs into the jQuery that pulled up the modal dialog on the master page.
Like I said, I'm not proud of this dirty, dirty fix. However, the consolation is that, since it's on the master page, there isn't really any naming container above it. As such, it's much less likely to run into problems with the clientID changing.
Assume I have the link http://www.somesite.com/file.aspx?a=1&b=2
And now I want to remove all the parameters, so it becomes:
http://www.somesite.com/file.aspx
Or I may want to remove only 1 of the parameters such as
http://www.somesite.com/file.aspx?b=2
Is there a way to do the above in C#? What is happening is that I am coming from another page with a parameter called edit in the url, but when the page does a post back, the edit parameter is still there, so it still thinks it is in edit mode. Example:
User A goes to page one.aspx and clicks on an edit link. They are taken to two.aspx?edit=true. During page load, it sees the the query string parameter edit is not null and it puts the contents in edit mode. Once the user is done editing, the page is refreshed, but the url is still two.aspx?edit=true and keeps the contents in edit mode, when in fact it should be two.aspx
Request.Querystring is read-only collection - You cannot modify that.
If you need to remove or change the param in querystring only way out is to trigger a new GET request with updated querystring - This means you will have to do Response.Redirect with updated URL. This will cause you lose the viewstate of the current page.
Use the PostBackUrl property, for example:
<asp:Button ID="DoneEditingButton" runat="server" Text="Done editing" PostBackUrl="~/two.aspx" />
When you are done with the edit you are doing a post back so just define the action to post to two.aspx instead of just posting back to itself that way it will drop off the get parameters.
How about checking Page.IsPostBack to see if the current request is a postback or not?
if you have only string, you can use:
strinULR.Split('?').First();
or
strinULR.Split('?').FirstOrDefault();
Try something like this.
if (url.Contains("?"))
url = url.Substring(0, url.IndexOf("?"));
In this example, I'm checking if the url even contains a query string, and if it does, subtracting getting the "left part" of the string prior to the ?.
Late but you can do this to remove query string from URL without another GET Request.
http://www.codeproject.com/Tips/177679/Removing-Deleting-Querystring-in-ASP-NET