I have a registration form and want to transfer the user to the success page, telling him that an email was sent to his email. I need to transfer his email from the register page to the success page.
I found about Server.Transfer, but I can't find out how to send parameters. I don't want to use query string as I don't like revealing information in the URL.
What is the proper way (if possible) to do this?
Server.Transfer("destination.aspx", true)
You might see that the above code contains the name of the page to which the control is transferred and a Boolean value ‘True’ to indicate to preserve the current form state in the destination page.
Set a property in your login page and store in it, the email.
Once this is done, do a Server.Transfer("~/SuccessPage.aspx", true);
On the other page, where you redirected, you should check something like that :
if(this.PreviousPage != null) {
((LoginPageType)this.PreviousPage).MyEmailProperty;
}
When you using server transfer you just move execution to different server handler , user will no see the new url or the parameters so it safe to make this transfer.
I would rather recommend that you do it differently.
When the user clicks the register button, you verify it all and then send the email from the still current page (so you need not transfer data to another page at all). If all went well, you just redirect:
Response.Redirect("/order/success.aspx");
If something was wrong (validation errors, sending email caused an exception) you are still on the right page for a retry. I would not use Server.Transfer at all in most cases.
You'll have to persist the value somewhere. The obvious options are in the Session object, or in a database.
For this kind of use case. You can use Context.Items to save the data with a key and read the value using the same key in the child page you are doing the Server.Transfer. Context.Items are sort of per request scoped cache for you.
Context.Items['DataKey'] = Data;
Server.Transfer("~/AnyRouteRelativePath", true);
Related
I know on client side (javascript) you can use windows.location.hash but could not find anyway to access from the server side. I'm using asp.net.
We had a situation where we needed to persist the URL hash across ASP.Net post backs. As the browser does not send the hash to the server by default, the only way to do it is to use some Javascript:
When the form submits, grab the hash (window.location.hash) and store it in a server-side hidden input field Put this in a DIV with an id of "urlhash" so we can find it easily later.
On the server you can use this value if you need to do something with it. You can even change it if you need to.
On page load on the client, check the value of this this hidden field. You will want to find it by the DIV it is contained in as the auto-generated ID won't be known. Yes, you could do some trickery here with .ClientID but we found it simpler to just use the wrapper DIV as it allows all this Javascript to live in an external file and be used in a generic fashion.
If the hidden input field has a valid value, set that as the URL hash (window.location.hash again) and/or perform other actions.
We used jQuery to simplify the selecting of the field, etc ... all in all it ends up being a few jQuery calls, one to save the value, and another to restore it.
Before submit:
$("form").submit(function() {
$("input", "#urlhash").val(window.location.hash);
});
On page load:
var hashVal = $("input", "#urlhash").val();
if (IsHashValid(hashVal)) {
window.location.hash = hashVal;
}
IsHashValid() can check for "undefined" or other things you don't want to handle.
Also, make sure you use $(document).ready() appropriately, of course.
[RFC 2396][1] section 4.1:
When a URI reference is used to perform a retrieval action on the
identified resource, the optional fragment identifier, separated from
the URI by a crosshatch ("#") character, consists of additional
reference information to be interpreted by the user agent after the
retrieval action has been successfully completed. As such, it is not
part of a URI, but is often used in conjunction with a URI.
(emphasis added)
[1]: https://www.rfc-editor.org/rfc/rfc2396#section-4
That's because the browser doesn't transmit that part to the server, sorry.
Probably the only choice is to read it on the client side and transfer it manually to the server (GET/POST/AJAX).
Regards
Artur
You may see also how to play with back button and browser history
at Malcan
Just to rule out the possibility you aren't actually trying to see the fragment on a GET/POST and actually want to know how to access that part of a URI object you have within your server-side code, it is under Uri.Fragment (MSDN docs).
Possible solution for GET requests:
New Link format: http://example.com/yourDirectory?hash=video01
Call this function toward top of controller or http://example.com/yourDirectory/index.php:
function redirect()
{
if (!empty($_GET['hash'])) {
/** Sanitize & Validate $_GET['hash']
If valid return string
If invalid: return empty or false
******************************************************/
$validHash = sanitizeAndValidateHashFunction($_GET['hash']);
if (!empty($validHash)) {
$url = './#' . $validHash;
} else {
$url = '/your404page.php';
}
header("Location: $url");
}
}
After checking a user's credentials and confirming they are good, I'm using FormsAuthentication.SetAuthCookie("Username", false); to authenticate the user.
In the masterpage I then use Page.User.Identity.IsAuthenticated to make sure we're dealing with a logged in user and not a guest.
The problem lies in first setting the auth cookie. When I set the auth cookie, immediately afterwards I run a method that uses Page.User.Identity.IsAuthenticated to change the welcome message from a generic "Welcome, guest!" message to a more personal "Welcome, username!" message. This does not work until I go to another page, so I know the login process has worked, but it seems I cannot access the information I need until a refresh or a redirect happens.
Do I need to redirect the user after setting the auth cookie in order use Page.User.Identity.IsAuthenticated to change the message?
I have seen this before so I know the answer is yes. (As in, yes you do need to redirect the user to correctly use Page.User.Identity.IsAuthenticated)
What I imagine is the cause is because IsAuthenticated evaluates the current request, and when the current request first came in it was recorded as not authenticated.
What you will need to do is apply whatever logic you have in said method without the check for IsAuthenicated (make it assume true).
Now I don't know the details of your method as to suggest how to re-factor it to cope with this, but you could split out the "Do Stuff" part into a separate function which you could then call directly from you login function to bypass the authentication check.
EDIT: To back up my assumption you can read this page.
The interesting part:
The forms-authentication ticket supplies forms-authentication
information to the next request made by the browser.
I'd like to point out that there's actually a way around this (since I've never seen this said in any other question like this). You can retrieve the cookie and its data where User.Identity's information comes from without a redirect. The thing is, the cookie just hasn't been sent to the browser yet.
It simply gets the cookie made by FormsAuthentication from the Response.Cookies object:
HttpCookie EncryptedCookie = Response.Cookies.Get(FormsAuthentication.FormsCookieName);
FormsAuthenticationTicket DecryptedCookie;
try {
DecryptedCookie = FormsAuthentication.Decrypt(EncryptedCookie.Value);
} catch (ArgumentException) {
// Not a valid cookie
return false;
}
// DecryptedCookie.Name: The Username
// DecryptedCookie.UserData: Any additional data, as a string. This isn't normally used
return !DecryptedCookie.Expired;
I have a page where I need to check for the presence of a cookie and then perform a redirect.
I have the code written (ASP.NET) to detect the cookie and perform a redirect. Pseudo-code:
HttpCookie myCookie = Request.Cookies.Get("theCookie");
if(myCookie == null)
{
myCookie = new HttpCookie("theCookie","myValue")
response.Redirect("page.aspx"); //Redirect to check for the presence of the cookie
}
More code...
When the user has cookies enabled, this approach works fine. When they have cookies disabled, however, they wind up stuck in an infinite loop (the page attempts to create the cookie, redirects, sees no cookie, then redirects again, ad infinitum). Most human users are probably going to be OK, but this will probably do a number on the site's SEO ratings.
I've wracked my brain for solutions, and since cookies are out of the question, that leaves viewstate and querystrings.
Because I've got to do a redirect, I think I'm stuck with querystrings. The problem is in order to detect whether a page has already been hit, I need to append a querystring to prevent the redirect from kicking in again.
Can anyone think of a way to accomplish this (preventing a redirect) without using cookies, viewstate, or querystrings? I think the answer is probably no...
Using a querystring in the manner you have described is the correct solution.
EDIT: looks like bad idea - query string is the approach. Keeping for reference: local storage as well as script can be disabled, so it needs to be considered when designing any client side detection logic.
You can also try to use local storage in browser to prevent infinite redirects. It will allow you to keep url clean from "?isCookie=true" query string. Note that you need JavaScript enabled for that. If you worried about cookies you should be worried about JavaScript disabled too.
What I wound up doing (in case someone else tries this) was using a couple of tricks:
Set up an ASP.NET hidden field control with its value set to false (default - cookies are disabled)
Used client-side script to check whether cookies are enabled
If the cookie gets set, cookies are enabled. In this case I use a jQuery call to change the value of the hidden field from false to true
Server-side, if the value of the hidden field is true, the page does the redirect. Otherwise, it just continues processing the page.
If the user has Javascript disabled, the value of the hidden field remains false, so the page is still rendered only once.
Thanks for letting me talk through it and getting me thinking!
// JScript File
function fnCheckBrowserType(var k)
{
if(k>0)
{
document.getElementByID('<%=HhdnBrowsertype.ClientID%>').value="1"
return true;
}
else
{
document.getElementByID('<%=HhdnBrowsertype.ClientID%>').value="0"
return false;
}
in.cs page load
Page.ClientScript.RegisterStartupScript(typeof(string), "fnCheckBrowserType", "fnCheckBrowserType();", true);
here i need to gets its return vale based on the return value "true " or "false"
i need to check the condition
pls help me to get the value from javascript to .cs page
thanks
prince
To send data to the server from the client, you have some options:
Send in a form.
Use Ajax.
Indirectly request a resource from the server and use a query string to send the information (for instance, adding an img element which uses a query string in its src). Not recommended, but possible and perhaps useful in some edge cases (for instance, when you need to send the data cross-origin and need to avoid the Same Origin Policy, as with many ad serving scripts).
Have the data piggy-back on your next normal request by setting a cookie.
Given the scenario you describe, Ajax may be your best option.
On my page a users (internal staff members) can type a comma separated list of e-mail addresses. What I would like to do is every time a comma is typed it checks that the newly written e-mail address is in the address book.
Currently I have the address book stored as a Hashtable for O(1) search times but I can easily switch to another data structure if it is recommended.
You can do that with JavaScript and AJAX to communicate with the server side.
You can do the next steps:
Create a web service that gets the string from the client (which is the email the user has typed), checks it and returns true/false.
Add [ScriptService] attribute to the
web service class.
On the page, add an ASP.NET
ScriptManager control with
Scripts/ScriptReference that points to the web service from step 1.
On the page, add javascript code that hooks to the onkeydown event of the emails textbox
In this event handler, if the user types a comma, execute a web service request to the server with the textbox value. When the respond (true or false) is received, do whatever you need with it.
You can read more on MSDN here and here.
You might also find helpful the AutoComplete AJAX extender.
In order for it to be done on keypress there is going to be javascript (or client side vbscript if you're using IE) involved. This cannot be done without it if you're looking to do it based on keyed input.
If you were to do it when the user leaves that text box, then you could use AutoPostback and code it in C# on the server side - I have to say though, I think that approach is ugly. Requiring a synchronous postback to validate data is a huge imposition on the user in my opinion and therefore should only really be a last resort or a stopgap while you're getting asynchronous script to do the work. You could also do it at post time (when they're trying to submit the form) and validate them and give the user back a validation message if any of the addresses fail, but once again, this is synchronous and the user doesn't get the benefit of early feedback.
I would do this using either a Windows Service (or use RESTful service) using a javascript call (using the XmlHttpRequest object). Bind your textbox's keydown event to a JavaScript method.
<input type="text" onKeyDown="javascript:CheckInput(this)" />
Then set up your javascript call - this is the guts of what's going on:
(Disclaimer: This code is not production ready, it's merely an example that should give you some direction)
var req;
function CheckInput()
{
if (window.event) keycode = window.event.keyCode;
if (keycode == 188) //KeyCode 188 = Comma;
{
//I haven't provided code for this, you will need to code
//the extraction of the address you wish to test for yourself...
var addressToCheck = ParseLastAddressFromTextBox();
req = new XMLHttpRequest();
//Replace <SERVICEADDRESS> with the URL of your web service
//the 'true' parameter specifies that the call should be asynchronous
req.open("POST", "<SERVICEADDRESS>", true);
req.onreadystatechange = MatchSearchComplete; //This is the callback method
//Set up the post headers
req.setRequestHeader("Host", "localhost");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var params = addressToCheck;
req.setRequestHeader("Content-Length", params.length);
//Iitiate the call to the service
req.send(params); }
}
//The XMLHttpRequest object will fire this method when the
//onreadystatechange event fires...
function MatchSearchComplete()
{
//Check that the response has the correct state and status
//indicating that we've received a response from the server.
if (req.readyState == 4 && req.status == 200)
{
//Our call to the service is complete
var result = req.responseText;
if (result == "false")
alert('The address "'+ req.params +'" is not valid.);
}
}
So what you're doing here is setting up an XMLHttpRequest, pushing the data into it and firing it off to a web service.
Your ASP.NET web application will need a web service built in to it that will be doing the validation of the address.
I might also warn: What if there's only a single address and the user doesn't hit the comma? You should move the guts of the CheckInput() method out to it's own method which parses the addresses. The KeyDown method really should only check if the ',' was pushed. This way you can call the web service to check when the textbox loses focus also. I would also worry about modification of existing addresses without the user hitting the comma again. Therefore, I would wonder about this approach. I would consider that once an address is validated you should have a javascript that only allows that address to be deleted, it shouldn't be editable... whatever approach you take, I'm just warning you that there's some issue with just checking them using the entered ',' approach.
You have to do this with Javascript. After the comma is typed, only then you can pass the email back to C# backend for verification.