2

I have a main web page ("Base Page") that makes an ajax call (using jQuery) to the server. The server-side page ("Ajax Page") is an ASP.NET web form (no MVC in use here). Because (in this case) I'm using a GridView to render data within the ajax response, I have to include the <form runat="server"> tag.

My complaint is this--when the Base Page receives the AJAX response, it inserts it into the DOM, but because the AJAX response is comprised of HTML markup that includes a <form> tag, this sometimes results in nested html forms, which is bad.

I realize that I can use jquery to only insert a fragment of the response into the Base Page DOM--or that I could use jquery to subsequently strip out the offending <form> tag. But these feel like klunky work-arounds. Is there really no way to prevent the ASP.NET page from serving out its response with a <form> tag? I realize that the form tag is the heart of the ASP.NET webform model, but it sure makes using AJAX in ASP.NET a complicated affair--very much swimming upstream. Surely Microsoft has realized that the postback / server-side model is a thing of the past?

I also realize that Microsoft has some server-side AJAX libraries that probably address this issue--but I'd still like to know if there's a solution native to ASP.NET webforms.

Any suggestions?

Octavient
  • 603
  • 3
  • 11
  • 21
  • 5
    This is not really a helpful comment, but this question just underscores why I dislike web forms - it is harder to control the output. I want byte-level control of what gets sent to the client. – D'Arcy Rittich Apr 19 '12 at 16:15

4 Answers4

3

Working with WebForms & AJAX for many years I can understand your frustration.

Usually when working with loading WebForm pages using jQuery AJAX, I wrap an ajax class around my page, just nested inside the form:

<html>
   <head></head>
   <body>
      <form runat="server">
         <div class="ajax">
            Content here..
         </div>
      </form>
   </body>
</html>

Then when I load the page, I call just this ajax class:

$("element").load("http://domain.com/webpage.aspx .ajax");

This means the form element isn't rendered into my page, preventing nested form issues, but your GridView can still be rendered into HTML successfully.

Curtis
  • 101,612
  • 66
  • 270
  • 352
  • Thanks for your reply. Yes, this is what I meant by inserting a fragment of the response. Two concerns here: a) this feels like a downstream work-around (though I suspect I'll just have to live with it), and b) when you use a selector in jquery's load method, any javascript that is included in the ajax response isn't fired, which is sometimes a problem (not all the scripts can be part of the AJAX load's callback function in the Base Page). – Octavient Apr 19 '12 at 16:44
  • Thanks, exactly what I was looking for. If you're using jquery, you have to use the "on" method to attach events to newly adding elements. http://api.jquery.com/on/ –  Nov 14 '13 at 15:39
3

You can add your GridView to a Web User Control and then render it to a string like this:

public static string ExecuteToString(this Control control)
{
    Page page = new Page();
    page.Controls.Add(control);

    StringBuilder sb = new StringBuilder();
    using (StringWriter writer = new StringWriter(sb))
    {
        HttpContext.Current.Server.Execute(page, writer, false);
    }
    return sb.ToString();
}

This means you don't need to point your ajax request to a page. You can use a web service. Query a specific method and then dynamically load the User Control, render it to a string and return the HTML. Because you put your HTML and code in a User Control you don't need to worry about stripping out form tags and you can still use all the asp controls as you would on a page.

I have no idea about the performance costs of using this method but I've been using it for a while and it seems fine to me.

Jon
  • 3,173
  • 3
  • 39
  • 66
  • Hmm... Interesting. This just might do the trick. Do you happen to know how to write this in VB? – Octavient Apr 20 '12 at 11:10
  • No, I'm afraid not - sorry. Incidentely this is set up as an extension so it can be called as a method on any control. – Jon Apr 20 '12 at 11:12
1

I was dealing with the same kind of issue, I resolved it the following way:

Response.Write("whatever content")
Response.End()

This will send ONLY what you put in "Response.Write()"... You're still free to alter headers, etc.

Clarius
  • 11
  • 1
0

If your ajax server page is an aspx page(ex : ajaxpage.aspx) , you can remove the HTML makup in the ajaxpage.aspx except the first line which mentions the Page directive. So it should be something like this.

<%@ Page Language="C#" CodeBehind="ajaxpage.aspx.cs" Inherits="MyProject.ajaxpage" %>

And in the code behind, you can return the data using response.Write

protected void Page_Load(object sender, EventArgs e)
{
   Response.Write("your markup to return here");
}

If it is to return some kind of (clean) HTML markup / some part of data, I am inclined to use a generic handler (ex : ajaxresponse.ashx )file instead of an aspx file and return data from that

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    context.Response.Write("<h3>Here is the Markup for UserDetails</h3>");
}

You can not use ASP.NET server controls on an ashx file. And you can not have a page to have a server control (ex : GridView ) without a form tag. It should be placed inside a form tag. Note that your server controls like gridview is going to render an HTML table markup only.

Personally if i want to get some clean & controlled HTML markup which i want to show /inject into my current page using ajax, i will use an ashx handler and write my code to output my required markup. ASHX files has performance advantages compared to a aspx file as it wont go thru the normal ASPX page life cycle ( All those events !).

Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Thanks, Shyju. For your response.write suggestion, wouldn't this mean that I can't use some of the controls, like the gridview? Is there a way to bind data to a gridview, and then response.write out the gridview? Same question for your ASHX suggestion--can I use controls like the gridview in these? – Octavient Apr 19 '12 at 16:41
  • @Octavient: I updated my answer. You can not use server controls in ashx files. if you want clean html and controller HTML, prefer ashx. – Shyju Apr 19 '12 at 17:12