Ssp
Ssp

Reputation: 21

Stop server side execution until user input and post back that value in server code in C# ASP.Net

I have button called Done with Onclickevent Done().

protected void Done(object sender, EventArgs e)
{ 
  private void Process(MyClass c, Mywebservice webservice)
  {
    if(c.Section.Elements.Any(element.SectionName == "area1"))
    {
      ClientScript.RegisterStartupScript(this.GetType(), "ShowPopup", "showAreaPopup();", true);
      return; //show popup and stop execution until user input is given for area1
    } 
    if(c.Section.Elements.Any(element.SectionName == "area2"))
    {
      ClientScript.RegisterStartupScript(this.GetType(), "ShowPopup", "showAreaPopup();", true);
      return; //show popup and stop execution until user input is given for area2
    }
    int MyArea1 = 0;
    if (int.TryParse(hiddenArea.Value, out Myarea1) && Myarea1> 0)
    {
        c.Details.Add(new Detail() { Name = "area1", Value = MyArea1});
    }

    int MyArea2 = 0;
    if (int.TryParse(hiddenArea.Value, out MyArea2) && MyArea2 > 0)
    {
        c.Details.Add(new Detail() { Name = "area2", Value = MyArea2});
    }
    webservice.Complete(this.CaseId); //this is a web service
}
  
}
function captureAreaVal() {
            var areaVal = document.getElementById('<%=TxtboxArea.ClientID%>').value;
            if (areaVal && !isNaN(areaVal) && parseInt(areaVal) > 0) {
                document.getElementById('<%=hiddenArea.ClientID %>').value = areaVal;
                closeAreaPopup();
                console.log("in captureAreaVal() ", areaVal);
            }
}

I want to write code such that when sectionName checked is area1/area2 or both, show popup immediately and wait until user input and capture that input in 'hiddenArea' and assign it to MyClass(with object c) property - Details and then execute the webservice for adding data to database. If none is checked just execute webservice. Can you please guide on how to postback the area value entered by user in server code. Is my requirement possible, if yes could you please help give/correct my code. Your prompt help is highly appreciated.

Thank you!

I have put flags to achieve my requirement but not helpful. Please help give/correct my code for achieving my requirement.

Upvotes: 2

Views: 74

Answers (1)

Albert D. Kallal
Albert D. Kallal

Reputation: 49264

You can't really pause server-side code.

Remember, the page and markup is modified server side. On client side, you see the typical browser "wait" spinner.

And the web server after it sends the whole page back to the client side will dispose, remove from memory the server-side code, memory, and toss out the web page. The web server is now waiting for ANY user, not just the one user to post back the web page and process that one web page.

Say on server side we have code to modify a text box from 1 to 10, but pause for 1 second.

        <asp:TextBox ID="txtBox" runat="server"></asp:TextBox>
        <br />

        <asp:Button ID="Button1" runat="server" Text="Count 1 to 10"
            OnClick="Button1_Click"                
            />

And code behind:

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        string sJava = "alert('Hello world);";
        ClientScript.RegisterStartupScript(Page.GetType(),"MyJava", sJava, true);

        for (int i = 0; i <= 10; i++)
        {
            txtBox.Text = i.ToString();
            System.Threading.Thread.Sleep(1000);
        }
    }

So, what will the user see?

They will see the browser "spinner" (wait) for 10 seconds while the server-side code modifies the web page. So, our script is injected to the web page - but the web page is STILL up on the server being modified by code behind.

Then after ALL the server-side code has run, then the WHOLE page is sent back to the client-side browser with all of the changes to the web "DOM" (document markup). Then the whole client-side page re-loads, JavaScript engine starts running code, and then your final web page is rendered on the client side.

Hence, it really does not matter if I inject the script before the for/next loop, or after, since code behind modifies the whole web page, and until 100% of the server side is complete, the user sees nothing, and is waiting for ALL of the server side to 100% complete its operations and modifying of the web page - including injecting scripts, and modifying of controls on that page.

In effect, code behind NEVER interacts with the user, never waits for the user, but can only make changes to the web page, and after any and all changes are made to that page (while the web page is up on the server, and while the user waits for all the changes to be made to that web page).

Hence, after 5 seconds of waiting, the changed page (now with text box = "3", and with the injected script are sent to the client side.

The effect they will see is thus this:

enter image description here

So, note how the user sees the browser "wait/spinner". So, you can inject all the script you want, and make as many changes to the browser WHILE it is up on the server - the end user see's none of these changes.

So, the page life cycle (a round trip) looks like this:

You have this:

enter image description here

Note how your page class - code behind is NOT in memory on the server.

YOU DO NOT have this:

enter image description here

And you do NOT even have this:

enter image description here

So, there is not a copy of the code and values and markup on the web server - the web server is waiting to process ANY page from ANY user.

NOTE VERY careful here - the web page is ON CLIENT computer - it is NOT existing at all on the web server side.

So, when you click on a button, or do a post-back, then you get the start of the round trip.

This:

enter image description here

Our web page is sent up to the server. You now have this:

enter image description here

NOW an instance of the page class is created, and your code behind starts running.

Your code behind can modify controls (even controls to be visible or not), but the page is NOT interacting with the user - ONLY code can MODIFY the web page (user does not see one change, or many changes).

One change, or MANY changes to the web page can occur, but AS YOU update things like a text box etc., the user does NOT see these changes just yet. So, if you run a loop 1 to 10, and update a text box, the txt box WILL be updated 1 to 10. However, the end user sees nothing, since that web page (and code) is running up on the server.

Changes to web page are occurring on the server - the client-side browser does not have the web page any more!

Once ALL of your code is done running, then and ONLY then does the page make the trip back to the client-side browser.

The server-side class instance and code (and variables) are TOSSED OUT - DOES NOT exist! Your server-side page class is disposed - removed from memory, and the web page code behind does NOT exist any more.

So, page travels back to the client side, is re-displayed, JavaScript is loaded, and THEN JavaScript starts running. So even the client-side page now 100% re-loads.

enter image description here

OK, this means that to display changes to the web page, the page MUST do a round trip. And if you using an update-panel, then that update panel MUST make a round trip! And this includes script injection.

Once you grasp how a web page round trip works, then you grasp why you can't have server-side code "wait" for user input, since server side does not interact with a user, but only interacts with the markup.

A great way to think of above? Think of a web page as much like an email message. You send a message, and wait for the user to reply. But, while the user writes their reply and builds up the return message, you see nothing and are simply waiting for the results. So, the web page "round trip" is much like an email messaging system.

So, how can you prompt and wait for input then?

Well, you flip the whole problem upside down.

What you can do is pop some dialog (client-side JavaScript) that prompts the user for input. When they hit ok, THEN you can run your server-side code.

You can even say have the server-side code inject the JavaScript to pop the dialog. And when the user done with the dialog, then hitting say ok button, then again server-side code can run. So, in effect, you have two parts.

Server-side code to inject code to pop the dialog, page round trip completes. Users see popup dialog or conformation dialog. Then when user hits "ok", then you have another post back (a new round trip), and code behind again runs based on the user having "ok" or "cancel".

In fact, in most cases, if the user hits cancel, then we don't have to run or do anything server side. And in most cases, we can often avoid injecting script to pop the dialog.

Buttons (in most cases) can have both a server-side event, and a client side click event. And if the client-side JavaScript returns true, then the server-side code click event will run. We can use this concept to our advantage by returning false if the user hits cancel, and thus server-side code simply does not run.

I also suggest you adopt some kind of dialog utility. Most popular are bootstrap dialogs and jQuery.UI dialogs.

So, let's setup a dialog to prompt for say first name, last name. So, we need both jQuery and jQuery.UI available in this page.

Hence this markup:

    <asp:Button ID="cmdGetName" runat="server" Text="Prompt for Name"
        OnClientClick="return myprompt(this);"
        OnClick="cmdGetName_Click"
        />

    <div id="mypopdiv" style="display:none">
        <h3>Please enter your name</h3>
        Enter First Name <br />
        <asp:TextBox ID="txtFirst" runat="server"></asp:TextBox>
        <br />
        <br />
        Enter LastName <br />
        <asp:TextBox ID="txtLast" runat="server"></asp:TextBox>
        <br />
    </div>

    <script>

        var okclick = false
        function myprompt(btn) {

            if (okclick) {
                // user clicked ok, return true
                okclick = false
                return true
            }

            var mydiv = $("#mypopdiv")
            mydiv.dialog({
                modal: true,
                closeText: "",
                dialogClass: "dialogWithDropShadow",
                title:"Get user name",
                width: '20%',
                position: { my: 'left top', at: 'right bottom', of: btn },
                buttons: {
                    Ok: function () {
                        okclick = true
                        mydiv.dialog('close')
                        btn.click()
                    },
                    Cancel: function () {
                        mydiv.dialog('close')
                    }
                }
            });
            return false
        }
    </script>

So, the jQuery. UI dialog pops a div on the page (but, with display:none, it does not show until we call the jQuery.UI dialog).

And code behind is this:

    protected void cmdGetName_Click(object sender, EventArgs e)
    {
        // process txtFirst and txtLastName from prompt

        string sFirstName = txtFirst.Text;
        string sLastName = txtLast.Text;

    }

And the result is now this:

enter image description here

If user hits cancel, then server side (button click) does not run. If user hits ok, then the button click code for the dialog will run.

So, as you can see, you can't halt server-side code to wait for a prompt (since everyone else on the web site would also be waiting for that page to be processed). Unlike desktop, you have ONE web server, and it will process page posted to the site, and then when done, will process the next page posted by some other user, or even the current user.

So, the architecture of web-based software is rather different then desktop land, and the above should help you grasp why some server-side code can't wait for user input.

Upvotes: 0

Related Questions