Artifis
Artifis

Reputation: 87

ASP.NET how to post updates during postback (I know how the postback works but still...)

Before I start - I know how the postback works, I know that page will update only when it is fully rendered, I just want to make sure, that there is no solution for my case to make minor updates to page.

Problem definition. I have ASP.NET project and a WCF service. WCF service contains few functions which return some string as result (e.g. was there mistake or did it go well). On the ASP.NET website I have a button, which fires sequence of actions. These actions are calls of functions from the WCF service. With usual postback (it is called ones I press the button), page will reload only when results for all functions are received as it should be (it takes quite much time). All results are added to a textbox.

Question. Is there any way really to add a result to the textbox asynchronously? I mean, really, using AJAX/something else, I do not care. I can not believe that this problem is unsolved in the ASP.NET. I just need a user to see progress - results of fired functions before the whole sequence is fired.

I spent few hours and I did not find any clue except UpdatePanel but I could not use it to solve the case. Do you have any ideas?

protected void Button1_Click(object sender, EventArgs e)
{
  textBox1.text += wcf.function1();
  textBox1.text += wcf.function2();
  textBox1.text += wcf.function3();
  //only now the page updates.
}

Upvotes: 0

Views: 360

Answers (1)

AiApaec
AiApaec

Reputation: 660

Demo using ajax and generic handlers. This example was made in MonoDevelop but you can pass to Visual Studio without changing the code. The folders and files:

/*
DemoGenericHandler
     |
     |---Default.aspx
     |---Default.aspx.cs
     |
     |---GenericHandlers
     |         |
     |         |---MyHandler.ashx
     |         |---MyHandler.ashx.cs
     |
     |---web.config

*/

This is the code for Default.aspx

<%@ Page Language="C#" Inherits="DemoGenericHandler.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head runat="server">
	<title>Default</title>
	<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
	
	<script type="text/javascript">
	
	$(document).ready(function(){
		var $button1 = $("#<%= Button1.ClientID %>");
		var $txt1 = $("#<%= textBox1.ClientID %>");
		var $txt2 = $("#<%= textBox2.ClientID %>");
		var $txt3 = $("#<%= textBox3.ClientID %>");
		
		var $progressBar = $("#progressBar");
		
		$button1.click(function(e){
		
			//avoid postback
			e.preventDefault();
			
			//show progress bar
			$progressBar.fadeIn('fast');
			
			//ajax-post
			$.post("<%= ResolveClientUrl("~/") %>GenericHandlers/MyHandler.ashx", 
					{data:"requestFromDefaultPage"},
					function(jsonInstance){
						if(jsonInstance)
						{
							$txt1.val(jsonInstance.Value1);
							$txt2.val(jsonInstance.Value2);
							$txt3.val(jsonInstance.Value3);
						}
						
						//hide progressbar
						$progressBar.fadeOut('fast');
					
					});//ajax-post		
		});//click
		
	});
	</script>
</head>
<body>
	<form id="form1" runat="server">
		<asp:Button id="Button1" runat="server" Text="Call Ajax!" OnClick="Button1_Click" />	
		<img src="http://casa-vivebien.com/contents/media/progressbar.gif" id="progressBar" title="" style="display:none;" />
		<br />
		
		<asp:TextBox ID="textBox1" runat="server"></asp:TextBox>
		<asp:TextBox ID="textBox2" runat="server"></asp:TextBox>
		<asp:TextBox ID="textBox3" runat="server"></asp:TextBox>
		
	</form>
</body>
</html>

This is the code-behind:

using System;
using System.Web;
using System.Web.UI;

namespace DemoGenericHandler
{
    public partial class Default : System.Web.UI.Page
    {

        protected void Button1_Click(object sender, EventArgs e)
        {
          //textBox1.Text += wcf.function1();
          //textBox1.Text += wcf.function2();
          //textBox1.Text += wcf.function3();
          //only now the page updates.
        }
    }
}

Code behind of the generic handler (*.ashx.cs):

using System;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Threading;

namespace DemoGenericHandler
{
    public class MyHandler : System.Web.IHttpHandler
    {

        public virtual bool IsReusable {
            get {
                return false;
            }
        }

        public virtual void ProcessRequest (HttpContext context)
        {
            //if you need get the value sent from client (ajax-post)
            //string valueSendByClient = context.Request.Form["data"] ?? string.Empty;

            //you must use a library like JSON.NET (newtonsoft) to serialize an object
            //here for simplicity i'll build the json object in a string variable:
            string jsonObj = "{\"Value1\": \"1\",\"Value2\":  \"2\",\"Value3\": \"3\"}";

            //await 5 seconds: (imitates the time that your wcf services take)
            Thread.Sleep(5000);

            //send the result to the client
            context.Response.ContentType = "text/json";
            context.Response.Write(jsonObj);
        }
    }
}

A capture: enter image description here

Upvotes: 1

Related Questions