Greetings.
I encountered a problem in accessing the controls I placed inside the TemplatedWizardStep tag. Here's the code snippet:-

<asp:Wizard ID="wizCreateBulk" runat="server" DisplaySideBar="false">
    <WizardSteps>
        <asp:templatedWizardStep ID="Step1" runat="server" Title="Select Recipient Method" StepType="start">
            <ContentTemplate>
                <div>
                    <span>Enter Name: </span>
                    <span><asp:TextBox ID="txtName" runat="server" />
                </div>
            </ContentTemplate>
        </asp:TemplatedWizardStep>
    </WizardSteps>
</asp:Wizard>

Then, in the vb side, when I tried to do txtName.focus() it returns control not found. I also tried Step1.FindControl("txtName") which returns System.NullReferenceException.

Please advise. Thanks.

you need wizCreateBulk.FindControl("txtName") the wizard control is the parent control not the templates...

it is possible but a bit tricky. And depends if you want to send the client there or not. In all cases you need to pass a variable in the request to b and then on page load you would need to check for this variable and call your sub then decide if you need to call the rest of page load or not. To do it by sending the browser you would need to create a public property for the variable in page a and then call response redirect or server.transfer to b. in Page load for b you would need to get the context.handler and then cast it to page a and then get the public property you created.
to do it behind the scenes you would be best to use the HttpWebRequest and add your variable to the content then handle it in page b page load again.

All the ways are pretty messy and not advisable. I would recommend you create a class which has the subroutine in it and then you can call the subroutine from any page cleanly and quickly.

Thanks for your fast response.
I have thought of doing the global class thingy that you have mentioned.
Then I thought it's quite inappropriate.
Alright, the scenario is this, from b.aspx.vb (child window), I'd like to call a function in a.aspx.vb (parent window) to pass some information to a control inside a.aspx.

How's that f1 fan ?

Thats a whole different scenario and requirements :) First it is better practice for a child not to know about its parent unless it is essential (in fact it is better if neither knows about each other - see the mediator pattern) but that is another topic all together.
From my understanding you have a form a.aspx and the user clicks a link to go to b.aspx where they fill in some information. When they have completed that you want to use the information back in a.aspx?
There are a number of ways to achieve this and you should not call a.method1 to do it. Use any one of the following:
1. use the session and add the values from b.aspx then when you are back in a.aspx get them out of the session and use them. Remember session means the data is going back and forth with every request and postback not just between a and b so clear any session variables you do not need as soon as you have finished with them
2 add the data to the response in b.aspx and get the data when you go back to a.aspx
3. add the data to hidden fields in b.aspx and get them in a.aspx when you get back (the difference between 2 and 3 is Get vs Post)
4. Put the data in a public property in b.aspx and register b.aspx in a.aspx then cast the context.header to b.aspx and get the data from the property (this would not be the recommended way for your requirements but sometimes is the only way)

If you are not sure on any of the above or want more information just shout. I am guessing 2 or 3 would be your best choice but depends how long you need to be able to access the data - maybe the session will be better

Thanks once again.
Umm, yeah, guess I need more information on the 2nd and 3rd options.
I'm not quite sure how it can be done but I have a rough idea here, did you mean that the form action tag of b.aspx should point to a.aspx so that the response could be posted to a.aspx ?

Also, I have always thought of session as the first choice but what always pulled me back is, I always have thought that session variables are to hold login information or other user preferences information, not to hold form results etc.

Session state can be used to store anything you want between sessions for a user (remember it is for a user not the application - there is an application state for that). Session is usually used for shopping carts and things like that. What you have to remember with a session is that the data is sent back and forth with every request from your user, not just for a page, but EVERY page and postback while they are on your site. So as long as you remember that and clear out any session variables as you finish with them (much the same as you should with any variable you use) then you can use it as much as you like.

But if it is just getting information from a page then there is no need to use the session. So we are back to options 2 and 3 from my last post.

For option 2: lets say in b.aspx you had 2 variables you needed to pass back to a.aspx. All you need to do in your response.redirect is call Response.Redirect("a.aspx?value1=" + val1 + "&value2=" + val2, true/false); then in page load of a.aspx just get those 2 variables by doing the following string value1 = Request.QueryString("value1"); string value2=Request.QueryString("value2"); The trouble with this is it appends it to the url so people can see it (the downside of a GET) so you can use a POST instead which uses hidden fields. This is option 3.

In b.aspx you need a hidden field for each value you want. You can do this either at designtime or runtime. Then when the user has finished you fill in the values hiddenfield1.value = txtbox1.value; etc etc Then just do a normal Respons.Redirect(a.aspx, true/false); this time there are no extras in the url. Though they can view source to see the fields in the middle of it all. but no biggie.

Then in page load of a.aspx you need to get the Request.Form which is a specialized name value collection where name is the hiddenfield id you created and value is the value you put in it. one for each hidden field. so you would do the following : string value1 = Request.Form("hiddenfield1"); string value2=Request.Form("hiddenfield1"); Hope that helps. Personally i would go for the post option (option 3) and keep things hidden

Wow, thanks for your thorough explanation.
All understood.
I will try that out.

Umm, I have another quick question here:-
I have been using the sqlDataSource control for about a week now but just recently came accross a situation whereby I need to build dynamic sql.
Initially, I opt to do things in the vb side where I'd do

sSQL = "select * from tableA where 1=1 "
if txtName.text <> "" 
  sSQL += "and vaNAME like '%" + txtName.text + "%' "
end if

if dtDate.text <> ""
  sSQL += "and dtCREATED > '" + dtDate.text + "' " 
end if

However, one problem encountered is, when using manual data binding, extra codes are needed to handle pageIndexChanged exception :(
So, I changed the strategy to go into using an sqlDataSource object. My code is as per below:-

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ... SelectCommand="select convert(datetime, dtCREATED, 103), *   from tableA where vaNAME like '%@vaNAME%' and dtCREATED > @dtDATE ORDER BY dtCREATED">
<asp:ControlParameter Name="vaNAME" ControlID="txtName" PropertyName="text" DefaultValue="" Type="string" />
<asp:ControlParameter Name="dtDATE" ControlID="txtDate" propertyname="value" DefaultValue="" Type="string" />
</asp:SqlDataSource>

My question is, Is the sql part in the selectCommand okay (especially the part highlighted in red) ?
I have tried all sorts of ways but to no avail.
Results aren't coming out.
Sorry for the long-winded post.

Your select command is wrong... you have where vaNAME like '%@vaNAME%' and ... where it should be where vaNAME like '%" + @vaNAME + "%' and ... Just as a matter of advice try to ALWAYS use stored procedures instead of writing sql queries in code. a few reasons - the main one is security i can bet money that you dont verify the text in the textbox is not sql commands and i would be in your database within 10 seconds (you wont believe the number of websites you can get into just from the login page - it is called SQL Injection and is usually number 1 on the hackers try list as it is so easy). What if i typed in the textbox something like this (pay attention to the ' ) in the textbox when you asked for my name... fred ' delete from master .... your whole sql server is wiped out now. took me less than 10 seconds. my simple ' in there closed your where clause (if you dont believe me go look at the sql statement with my text substituted for the variable) and allowed me to run my delete sql statement (yes you can have multiple sql statements one after the other, they dont have to finish before sending the next one)
So that is the main reason to use stored procs - you dont put in the ' round text so no sql injection can take place. The second reason is performance. Stored procs are compiled and run on the server. This means they are quicker, can be cached, you can run index analysis on them etc. Also what if you needed to add a new where clause? You would have to send out your program to everyone again after rewriting the new where clause. Would you get everyone? If it was for a new column that didnt allow nulls these people couldnt use your app until you changed it (assuming a central database) so not backwards compatible. Whereas with a stored proc you have only one place to change it, it is backwards compatible (assuming you code it correctly) and it takes effect immediately.

Comments
Thank you very much for the valuable lesson :)

Thanks a lot f1fan for the thorough explanation~!
I must say that I learned a lot from that reply lol.
Now I know what sql injection means - thanks a lot.

Its part of my job - to find security holes in web sites and i think i can get into about 25% of so called "restricted access" websites within 30 seconds by SQL injections. Without knowing anything other than this post i would put money on the fact you are using the SA login, i would also put some good money on the fact that at least 25% of people reading this post are using the default SA password. I would also put money on the fact that 75% of "internal" applications (ie those that are within a lan/subnet for internal use only and not anywhere near the web) use windows logins for authentication and database access (then they wonder why their data is corrupted because all the users are linking access and excel spreadsheets to the data and changing it bypassing the integrity checks.
And just as some casual information... the most popular administrator password is.......... wait for it.... CONTROL

Interesting... Would you mind sharing what's the basic steps needed to secure your web ?

the very first and most important step is good programming. I cant stress it enough. Test for every eventuality. Too many people think error handling is a try catch block around everything. Secondly implement some login mechanism. Only allow people in the areas you specifically want them in so structure your site with subdirections. Validate every input at least 2x. Once on client side as best as you can (using the validator controls) and once on the server side (and if you can - in the database before a save). Use roles where needed. NEVER use querys in code ALWAYS use stored procedures. Disable the SA login in SQL Server and create a new one if you need to have a non windows one. Do not give windows accounts db permissions (except to DBAs and developers) always use application accounts. Encrypt passwords for connection strings and encrypt connection strings. Hash user passwords. Use strong passwords (a strong password for those who do not know is made up of upper and lower case letters, numbers and symbols). For those who say a strong password is too hard to remember try this. Make up two small words that are not associated (eg car knife) now substitute some symbols and numbers in there (@ or 4 for an A and ! or 1 for an I, and 3 for an E, $ or 5 for an S) and uppercase the first letter of each word. So your password is now C@rKn1f3 Thats a strong password, hard to break and easy to remember - just remember car knife and your substitutions. If you always use the same substitutions eg @ for A then it will be easy to remember and is very strong. If you let people make posts etc on your site then watch for cross site scripting. This is people putting javascript in links etc on your site. It recently happened on ebay where they put javascript in their listings to take people to a spoof login page and got their names and passwords. they managed to slip through ebays java detector (ebay lets you put some javascript on your listings). Use firewalls where you can. Only expose code on the website you need to, keep the rest behind the firewall. Use SSL where you can. Remember you wont keep everyone out. For those that do get in you want to be alerted that they are in and you want to know what they have changed or looked at when they are in.

Only allow people in the areas you specifically want them in so structure your site with subdirections

Should say structure your site with subdirectories. i should pay attention when i type.

Thats a whole different scenario and requirements :) First it is better practice for a child not to know about its parent unless it is essential (in fact it is better if neither knows about each other - see the mediator pattern) but that is another topic all together.
From my understanding you have a form a.aspx and the user clicks a link to go to b.aspx where they fill in some information. When they have completed that you want to use the information back in a.aspx?
There are a number of ways to achieve this and you should not call a.method1 to do it. Use any one of the following:
1. use the session and add the values from b.aspx then when you are back in a.aspx get them out of the session and use them. Remember session means the data is going back and forth with every request and postback not just between a and b so clear any session variables you do not need as soon as you have finished with them
2 add the data to the response in b.aspx and get the data when you go back to a.aspx
3. add the data to hidden fields in b.aspx and get them in a.aspx when you get back (the difference between 2 and 3 is Get vs Post)
4. Put the data in a public property in b.aspx and register b.aspx in a.aspx then cast the context.header to b.aspx and get the data from the property (this would not be the recommended way for your requirements but sometimes is the only way)

If you are not sure on any of the above or want more information just shout. I am guessing 2 or 3 would be your best choice but depends how long you need to be able to access the data - maybe the session will be better

Hi,

I have a user control, with an ASP Wizard control inside it.
This control, generates the steps in the wizard dynamically, going throug a data object, and creating the steps and fields, adding the controls to each step, and a new step for a new group of controls.
This is done on the User control DataBind() method

override void DataBind()
{
      base.databind();
      createWizardSteps();
}

Now.....
I am having a couple of different issues.
If in the Databind, I set ActiveWizardStep = 1, then the first time my page loads with the control, i see the wizard fine, but then when move to a nother step, i keep getting an error saying that ActiveStep = 2, must be lowerd than wizard stieps, etc.....

1) in what event of my user control, do i need to create the wizard steps? so that they maintain after postabcks? I would really like to only add the controls once on first page load, and then viewstate should be maintianed till the wizard is complete or submitted.

2) do you know of any sample code creating a wizard dynamically through code?
for example if in my app_code i wanted a method that did something like

public Wizard GetChairConfigurationWizard(int chaidID)
{
     Wizard retWizard = new Wizard();
     ... code to get groups and controls for wizard..
     ... foreach( Group   )
               ...  retWizard.WizardSteps.Add(createWizardStep(Group)
     .....
     return retWizard;
}

any help or guidance would be appreciated. Thank you,
Jonathan

Hi,

I have been trying to dynamically add wizard steps to the wizard but, I have not been able to. Could you please tell me how you manage to add wizard steps to the wizard control. The code looks like this:

WizardStepBase wizardStepHelper = null;
            wizardStepHelper = new WizardStep();
            wizardStepHelper.Controls.Add(new TextBox());
            wizardStepHelper.StepType = WizardStepType.Start;
            Wizard1.WizardSteps.Add(wizardStepHelper);
            for (int j = 1; j < 3; j++)
            {

                wizardStepHelper = new WizardStep();
                wizardStepHelper.Controls.Add(new TextBox());
                wizardStepHelper.StepType = WizardStepType.Step;
                Wizard1.WizardSteps.Add(wizardStepHelper);

            }

            wizardStepHelper.Controls.Add(new TextBox());
            wizardStepHelper.StepType = WizardStepType.Finish;
            Wizard1.WizardSteps.Add(wizardStepHelper);

Could you please tell how you manage to dynamically add wizard steps to the Wizard...

Thanks!
I really appreciate it!!!

Edited 3 Years Ago by pyTony: fixed formatting

you need wizCreateBulk.FindControl("txtName") the wizard control is the parent control not the templates...

Ive tried both:
Step1.FindControl("txtName")
wizCreateBulk.FindControl("txtName")

But still get the Null exception error. Any Idea what i Am doing wrong?

This article has been dead for over six months. Start a new discussion instead.