0

I need to get a value (ClientId) from localStorage to code-behind. This is handy for logging in with a 'client' setting from a previous session, stored with:

C#:

string script = string.Format("localStorage.clientId = '{0}';", _MySession.CurrentClientId);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key", script, true);

(see: this SO question)

To get the data back from localStorage to code-behind, the asp.HiddenField element seems to be made for this: the element can easily be written with JavaScript and can be read from code-behind:

HTML:

<asp:HiddenField ID="hf_ClientId" runat="server" />

JS:

document.getElementById("<%=hf_ClientId.ClientID%>").value = localStorage.clientId;

code-behind, C# (in a MasterPage):

var v = hf_ClientId.Value;

However, the code-behind is in Page_Load, and runs before the html is constructed and the JS is run in $(document).ready, so no value is received.

Then I tried to move the JS to theForm.onsubmit which is run as a hook by __doPostBack. With the Firefox F12 debugger and the VisualStudio C# debugger I verified that the JS is called before the C# as soon as a postback occurs by clicking some button on the form, but still no value received there.

What am I doing wrong and how to fix this?

Roland
  • 3,391
  • 5
  • 32
  • 63
  • If you want to assign a value to hidden control which is declared `run at="server"`, then you simply do `hf_ClientId.Value = somevalue ;` in code behind – Chetan Ranpariya Aug 07 '18 at 13:48
  • @ChetanRanpariya True, but that does not yet store the value in localStorage. Here I need to move the data from the client side back to the server code behind. Any suggestions? – Roland Aug 07 '18 at 13:50
  • if you want to send data from client to server, you have to make another HTTP request, either via postback or AJAX. This will cause some C# code to run, at which time you can make use of the value sent from the client. – ADyson Aug 07 '18 at 13:51
  • @ADyson True. I was thinking that the submit and the associated postback and hiddefield would work for me – Roland Aug 07 '18 at 13:52
  • The flow goes like this - Page is loaded the first time. At this point the client HTML doesn't even exist. Server sends HTML to client. Client displays HTML, runs Javascript. So at this point you can grab your value from localstorage on the browser. Now to send it back to the server you have to make a postback or AJAX request, and initiate another run of the C# code. – ADyson Aug 07 '18 at 13:54
  • P.S. it sounds like you're trying to store some kind of login-related info? Wouldn't it be simpler to use cookies? – ADyson Aug 07 '18 at 13:55
  • @ADyson But why did the postback from the submit not bring the value of the hiddenfield??? – Roland Aug 07 '18 at 13:55
  • @ADyson There are several alternatives, cookies, server database, etc. But localStorage, when working, should be very simple and lightweight. Please help with localStorage – Roland Aug 07 '18 at 13:58
  • It's not clear in your question - you talk about Page_load being run...are you talking about running this during a Postback of the form which contains your hidden field? It's confusing, because you mention that it runs before the HTML is constructed. In the context of the current request, that's true, but if there was a postback then it should also bind to the hidden field value sent from the browser in that postback. Did you watch in your browser tools to see if the hidden field was definitely populated by the JavaScript before you posted back? – ADyson Aug 07 '18 at 13:59
  • @ADyson Good point. I guess __doPostBack does only send the value of one control to code behind, not the hidden field !!?? I am now trying this: https://stackoverflow.com/questions/6349155/hiddenfield-value-lost-on-postback – Roland Aug 07 '18 at 14:05
  • AFAIK doPostback submits the whole page. Been a while since I used WebForms (MVC is 1000% times easier to work with) but that's my understanding. Like I said, check that your JavaScript is actually doing its job properly before you post back. Perhaps the script runs before your HTML hidden field is rendered, for instance, in which case it has nothing to populate. Check your console for errors, check the current HTML elements for the value of the field (or run a command in console to read it) – ADyson Aug 07 '18 at 14:07
  • Maybe this will help: http://stephenwalther.com/archive/2011/01/12/asp-net-and-html5-local-storage – VDWWD Aug 07 '18 at 14:41

3 Answers3

2

Reading this SO question I tried a much simpler hidden field:

HTML:

<input type="hidden" id="hf_ClientId" name="hf_ClientId" />

C#:

if (IsPostBack)
  string StoredClientId = Request.Form["hf_ClientId"];

The Javascript is also simpler, as the runat=server attribute is gone:

JS:

document.getElementById("hf_ClientId").value = localStorage.clientId;

or, using jQuery (not tested, the val syntax might be wrong):

$('#hf_ClientId').val(localStorage.clientId);

This works, there is data now.

As a bonus, the C# part can be in the MasterPage, where the hidden field is located, or in the main Page. Just add a comment, because it is kind of spaggetti.

Because, for me, this is a login page, this C# code is in the callback of the Login button, so it is always a PostBack. Simple!

Roland
  • 3,391
  • 5
  • 32
  • 63
1

I think, you're debugging the first (initial) request. Here the HiddenField is not set. To see the HiddenField value, you must debug the code AFTER it has been posted to the server. Try adding a check in your Load event:

    if (Page.IsPostBack)
{
    //Here you can read your hidden field
}
Poul Bak
  • 7,390
  • 4
  • 20
  • 40
0

Try adding document ready to the codebehind javascript call

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key", "$(document).ready(function(){'" + script + "'}", true);
ADyson
  • 44,946
  • 12
  • 41
  • 55
drzounds
  • 334
  • 2
  • 15
  • This is same as my posted code, except you use JS '+' instead of string.Format, and getting data from code-behind to JS was no problem. But can you also get values back from client to code-behind using RegisterClientScriptBlock? – Roland Aug 07 '18 at 14:20
  • @Roland it's not the same, it uses a jQuery document.ready() block to ensure that the code to populate the hidden field doesn't run until all the elements on the page are ready - ensuring that the hidden field definitely exists in the browser DOM when the code runs (because if it doesn't, the field won't get updated, and then the value won't be posted back). Your version doesn't have that. It's not a bad suggestion, although drzounds should have attempted to explain the reason for it. Note that I alluded to this possibility in one of my comments on the main question, above, a while ago. – ADyson Aug 07 '18 at 14:28
  • @Roland P.S. If you want to do the equivalent thing without having to use jQuery then see here: https://stackoverflow.com/a/800010/5947043 – ADyson Aug 07 '18 at 14:32
  • @ADyson I mentioned in my post usage of $(document).ready . Also, this is about getting data from server to client, which is working fine. My problem is the other direction – Roland Aug 07 '18 at 15:14
  • The reason you can't get data from client to server is that the hiddenfield is not populated correct? This could populate the hiddenfield in a way so the value is populated when you try from the server. – drzounds Aug 07 '18 at 15:20
  • @Roland yes, you said ""the JS is run in $(document).ready"... ok you did mention it but really it's better to actually show it in the code snippets, so it's 100% clear that you did that, not just in the description. What you should do though is check your rendered HTML to see if the ` – ADyson Aug 07 '18 at 15:27
  • @Roland ....."this is about getting data from server to client,"...what goes from server to client is the JavaScript. What we're trying to do is get the JavaScript right so that it facilitates the sending of data from client to server, by updating the relevant field. Will you **please** answer my question above regarding whether your hidden field is in fact populated correctly or not prior to postback? It's quite a key point. Also it would be useful to check - do you have any errors in your browser's console? Do you understand what I'm asking you to do? – ADyson Aug 07 '18 at 15:32
  • @ADyson We can make a big discussion here, but the key point is that reading from localStorage to code-behind involves two steps: 1) a http-get to load a page with javascript that reads from localStorage to a hidden field, then 2) a submit with http-get/post or an ajax call to get the value of the hidden field to the server. The method using RegisterClientScriptBlock is complex and not needed, as a hidden field can be used instead; also using that call to write to localStorage was already working and not my problem.Thanks for thinking with me anyway. – Roland Aug 14 '18 at 15:28