Problems reading form variables in asp.net C# [closed] - c#

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Background: I've been asked to work on a legacy asp.net application for which there is no documentation and the original programmers are not available for consultation. I'm primarily a Perl programmer, primarily on *nix systems, so while I've no major problems with the actual logic of the system, I'm getting tied in knots by some of the "bare bones" stuff underneath.
Outline: I'm trying to extend an existing aspx form to increase its functionality, the form is part of a system for purchasing telephone numbers. At the moment, the form when first called shows a list of locations and telephone area codes in an HTML drop-down list, and expects the user to select one. When a value is selected (or selected and the select button clicked, if JS is disabled) and the form submitted, the page in postback mode then provides an appropriate redirect to a purchase page, with various values set in the query string. I want to extend the functionality by adding a second row of controls, on the same form, comprising a text box for users to enter an area code, and a "Search" button. The idea is that when a user does this, the system will then do a DB search for that area code, and if a match is found, generate the appropriate redirect to the page selling that area. All the code is (and will be) in C#.
The problem: Having found a lot of useful info here on Stack Overflow on extracting form variables from asp.net forms, I tried to retrieve my new variables using Request.form["variable_name"]. But it soon became clear the values weren't coming through.
Here's the aspx page code for the new bit of the form:
<tr>
<td align='left'><b>STD code:</b></td>
<td align='left'>
<asp:TextBox id="STD_Code_Search"
AutoPostBack="True"
Columns="7"
Text=""
TextMode="SingleLine"
Wrap="False"
runat="server"/>
</td>
<td><asp:Button ID="Button2" runat="server" Text="Search" /></td>
</tr>
I expected to be able to pull those variables back via
Button2_Clicked = Request.Form["Button2"]
STD_Code_Search = Request.Form["STD_Code_Search"]
However nothing ever came through. Based on more searches, I found this code to display all the variables coming into the form:
foreach(string key in Request.Form.Keys)
{
LOG.WriteLine(key + ": " + Request.Form[key] + "<br/>");
}
The LOG object is a StreamWriter going to a text file, which seems to work fine.
However the data in the file looks like this:
ctl00$ctl00$ctl00$ContentPlaceHolder1$Main$Range_Data$STD_Code_Search: 01952<br/>
ctl00$ctl00$ctl00$ContentPlaceHolder1$Main$Range_Data$Button2: Search<br/>
Fair enough, I then tried to use the following to retreive the data in C#
STD_Search = Request.Form["ctl00$ctl00$ctl00$ContentPlaceHolder1$Main$Range_Data$STD_Code_Search"];
That does actually work and if I send STD_Search to the StreamWriter LOG I can see the entered value in my text file.
However if I then try and read a second value (in this case I'm trying to catch the value of Button2, so I can trigger specific behaviour if that button, rather than the original one, is clicked), using this code:
STD_Search = Request.Form["ctl00$ctl00$ctl00$ContentPlaceHolder1$Main$Range_Data$STD_Code_Search"];
Button2_Clicked = Request.Form["ctl00$ctl00$ctl00$ContentPlaceHolder1$Main$Range_Data$Button2"];
Then while the asp.net processes all appear to complete correctly (no errors or page crashes), the writing of the text file stops dead and no data at all is written.
Questions:
I'm sure I shouldn't have to include all the placeholder stuff
(reading on here I gather that's part of the underlying framework
and asp should in fact just present me with the named variables, the
same as a Perl or PHP system would do with a plain HTML form), any
pointers as to why that might be happening and if there's anything
else I should be doing to process / extract the data?
Why does it all drop dead when I try and read in a second variable,
despite working (for some large values of working) when I only read
in one?
Are there any recommended books on asp.net and C#? I have
Sitepoint's "Build your own asp.net 4 website using C# & VB", which
has helped a bit but isn't so useful for trying to take someone
else's code apart and re-build it.
Prior research: I've done extensive searching on this, however most of the answers I've seen so far have been related to people using asp.net to process data submitted from external sites, etc, or by scripts using post directly. All the sites I've looked at for tutorials on asp.net appear to say I should just use Request.Form["variable_name"], so there appears to be something else going on here.

You should be using code-behind to do all this stuff. It will make it easier.
string searchText = STD_Code_Search.Text;
And to to know if a button was clicked, you would do
<asp:Button ID="Button2" runat="server" Text="Search" OnClick="Button2_Click" />
And have it processed
protected void Button2_Click(object sender, EventArgs e)
{
//button2 was clicked
}
Asp.Net is an event-driven framework, not like PHP or JSP. Pick a good book on Asp.Net and read. Most of the things you were trying to do have been handled for you by Asp.Net.

The Request.Form collection is only used when you want to access "raw" POST body contents directly. ASP.NET WebForms operates an abstraction layer which means you shouldn't normally need to use this collection.
Instead access submitted values by their parent controls. In this case the control is known as "STD_Code_Search" (an egregious violation of .NET's naming and style conventions, but I digress). Assuming you're using Visual Studio's tools, there will be an auto-generated file with the same name as your *.aspx file with the suffix "designer.cs" that will contain a class field called "protected TextBox STD_Code_Search;". All you need to do is access this field. Note that this field will only be populated after the Init page event.
string search = STD_Code_Search.Text;

Did you try how its supposed to work?
You should have a protected variable for each form control in your .cs file. Newer versions of visual studio do this for you (when you add server side markup tags), but basically if you've no intellisense in the .cs file for the variable .g.
STD_Code_Search
If it's not declared, just do this at top of page:
protected TextBox STD_Code_Search;
now when you post back STD_Code_Search.Text should have a value
That as I've said is how it should work.
Unless there's some compelling reason to use Request.Form you shouldn't go there, but its worth knowing its whatever is wrriten in the "name" attribute on the client-side (hence that horrendous placeholder stuff). It can be overwritten to something more pretty (options based on your asp.net version).

Related

asp:HiddenField being cached server-side somewhere?

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)

Handle OnClick in C# or JQuery

I am working on a webforms project using c#/aspx/jquery. I'm not sure where to handle my Onclick. Both options (doing it in C# or jquery) seem feasible. Which would be better practice?
Here is the scenario:
I want to build a checkbox which will toggle a textbox's textmode, altering it between Password and SingleLine.
Currently, I have this following code for my markup since I am currently handling it in C#:
<asp:Checkbox ID="CheckBox1" OnCheckedChanged="CheckBox1_OnCheckedChanged"/>
The code:
protected virtual void OnCheckedChange(EventArgs e)
{
If (CheckBox1.TextMode == TextMode.Password)
CheckBox1.TextMode = TextMode.SingleLine;
else
CheckBox1.TextMode = TextMode.Password;
}
The use case of this is: A user is entering his password. On the same page, he may choose to keep the password hidden or not by checking the checkbox.
Which would be better practice?
What is your functional requirement?
Setting this in C# on the asp.net code behind, you will need a post-back to make it work. This means the page will refresh and the text box will change.
On the client (JS/JQuery) the page will not refresh.
Now you evaluate the work required vs the quality you need. (If you want a nice user experience and are ok with writing JS put it in JS, if you're strapped for time and are ok with the refresh then do it on asp.net).
I'm trying to answer your question in general sense about HOW such a decision (in my humble opinion) should be made. Realistically this is very simple to implement in javascript and your should do it there.
Now for the code (I assume you know how to put it in asp.net code behind so I'm going to write the JS approach):
Html:
My Password: <input type="password" id="mytext" /> <br />
Hide Chars : <input id="passChk" type="checkbox" checked="true" />
Javascript:
$(function() {
$("#passChk").change(function(){
if(this.checked) {
$("#mytext").attr("type","password");
} else {
$("#mytext").attr("type","text");
}
});
});
See it running here: http://jsfiddle.net/rC5NW/2/
After trying to implement the accepted answer, I realized that some browsers (I used Google Chrome) does not allow changing the type attribute. There is a way to bypass this but I don't think it is worth it for my purposes:
Therefore, It might be better to just use C#.
Relevant Questions
Does javascript forbid changing the input type from password or to password?
change type of input field with jQuery

Text with RegEx Validator not working

I have an issue with the following text display:
<asp:RegularExpressionValidator ID="Password_RegularExpValidate" runat="server"
Text="TEST!"
Display="Dynamic"
BorderStyle="None"
ControlToValidate="txtNewPass"
ValidationExpression="(?=^.{8,255}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*"
meta:resourcekey="Password_RegularExpValidateResource1" /></td>
The pattern by itself is:
(?=^.{8,255}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*
The text initially had some stuff in it as the ValidationExpression was different. I've changed the regex expression and that works, but when I write something in Text= it doesn't update on the page. I've restarted IIS, cleard the IE chache... everything I could think of. The old text keeps appearings (ie. "TEST!" doesn't show up when the validation fails as it should).
Any help would be appreciated.
Edit:
The code for txtnewpass:
<asp:TextBox ID="txtNewPass" runat="server"
TextMode="Password"
MaxLength="256"
meta:resourcekey="txtNewPassResource1"></asp:TextBox>
Also, it's worth noting that I can remove an entire table from a page that it disappears when I reload the page. But when I change text values from controls or anything that runat="server" and the page doesn't seem to update with the text....
And the code behind doesn't edit the field that displays, the validator validates the text in the textbox and uses that value later.
Edit 2: Same thing happening with -
<asp:Label ID="Label1" runat="server"
Text="Change Password!!!!!"
meta:resourcekey="Label1Resource1"></asp:Label></td>
I've added the exclamation marks (!!!!!) and that's not showing up when I refresh the page either.....
Edit 3: As I've noted in one of the comments, if I delete a table from the page and reload the page, that table disappears, so I know the page is reloading properly. The runat="Server" property, does that work a certain way where it caches text or something? I'm out of ideas....
Like Kirill said, use ErrorMessage instead of Text.
But the main problem is, I think, your localization, which is handled through the meta:resourcekey tag and resources.
Here is a good explanation:
ASP.NET meta:resourcekey
If you set automatically or manually the resource localization file and change something afterwards, for example a Label Text property, then you need to do it in the resource file too. Because there should be your initial value, which is loaded at runtime.
There are a lot of possibilities for the source of the problem, and there's not really enough info to tell which one it is. It sounds to me like one of these:
1) An external issue with your application or page (perhaps your ViewState isn't being set up properly, or the validation is getting called before PostBack).
2) You should be using RegularExpressionValidator.ErrorMessage instead of Text, as Kirill suggested. You said that you had changed that, but I wonder if you've reloaded the page (you could try rebuilding the app or something if it's getting cached somehow).
3) Your regex might not be doing what you think it is. The pattern is extremely long, and it seems strangely written. Adding some whitespace, we find that it looks like this:
(?=^.{8,255}$)
(
(?=.*\d)(?=.*[A-Z])(?=.*[a-z])
|
(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])
|
(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])
|
(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9])
)^.*
Which simplifies down to something like:
^(
(?=.*[A-Z])(?=.*[\W_])(?=.*[a-z\d])
|
(?=.*[a-z])(?=.*\d)(?=.*([A-Z\W_]))
).{8,255}$
Is this what you intended? I see where you're going with the password rules, but it may be easier to just simplify them and require one capital, one lowercase, one number, and one special character. You could also try to get validation working with a simpler regex pattern, and then add complexity once everything else is working.
Try to use RegularExpressionValidator.ErrorMessage instead of Text.
Try restarting VS. Sometimes incredible bugs disappear after that.
Try removing and regenerating your ..aspx.designer.cs file (to
regenerate right click the aspx/ascx file and choose "convert to web
application").
Agree with others, you should indeed check your resource file.

C# - Get JavaScript variable value using HTMLAgilityPack

I currently have 2 JavaScript variables in which I need to retrieve values from. The HTML consists of a series of nested DIVs with no id/name attributes. Is it possible to retrieve the data from these variables using HTMLAgilityPack? If so how would I go about doing so, if not what would be required, regular expressions? If the latter, please help me in creating a regular expression that would allow me to do this. Thank you.
<div style="margin: 12px 0px;" align="left">
<script type="text/javascript">
variable1 = "var1";
variable2 = "var2";
</script>
</div>
I'm assuming you are trying to scrape this information from a website? Most likely one you don't have direct control over? There are several ways to do this, I'll go easy to hard( at least as I see em):
Ask the owner (of the site). Most of the time they can give you direct access to the information and if you ask nicely, they might just let you have it for free
You can use the webBrowser control, run the javascript and then parse values from the DOM afterwards. As opposed to HttpWebRequest, this allows for all the proper values to be loaded on the page and scraped. Helpful Link Here.
Steal the source with Firebug. Inspect the website with Firebug to see which URLs are called from the background. Most likely, its using an asynchronous request to retrieving the updated information from a webservice. Using Firebug, you can view this under the NET -> XHR. Look at the request and the values returned, you can then retrieve the values your self and parse the contents from the source rather than scrape the page.
I think this might be the information you were looking for, but if not let me know and I can clarify/fix answer

calling a javascript function in C#

Hi i wanted to show or hide duplicate records according to query. So, I need to know how to call the javascript function from C# codebehind.
<a onclick="Grid1.insertRecord(); return false;" id="a2" href="javascript:">Save</a>
When I click save i need to show a popup which i have written in javascript.
if (!exist)//exists is the query
{
System.Web.UI.Control my = FindControl("a2");
a2.Attributes.Add("onclick", "retrun HideDuplicate()");
This line returns an error saying "a2 doesnot exist in current context."
Why not use an asp.net LinkButton? It has a server side Click event and is accessible from c# code-behind.
The basic <a> tag is not turned into a control by asp.net unless you add a runat="server" to it. Its then turned into a HtmlGenericControl.
<a onclick="Grid1.insertRecord(); return false;" id="a2" href="#" runat="server">Save</a>
This might work for you - its not clear if you have more than one of these links on the page (such as in a row of a gridview?) or if its just on there once.
Also the way you have used javascript is not following best practices but thats a discussion for another day :)
MSDN documentation for programatic creation of client side callbacks without postback with an example where the code behind is in C# might give a good overview of how it is supposed to work in general.
In your case, the corresponding code-behind should implement the interface 'ICallbackEventHandler' and the two methods it describes. In addition, you would need two more client side Javascript functions to prepare and handle the callback, besides the executor/invoker (in your case, a 'save' method). However one of the additional two Javascript functions could be registered in the codebehind, as the example shows.

Categories