如何在没有来自服务器的两个完整页面呈现的情况下将WebForms页面加载到iframe中?

时间:2022-05-21 07:19:04

I have a sort of shell page that contains filter controls and an iframe for displaying a gridview. When you click the 'filter' button, or when a timer is fired, filter data is collected from the filter controls and fed in the querystring to the gridview iframe, as shown:

我有一种包含过滤器控件的shell页面和一个用于显示gridview的iframe。单击“过滤器”按钮或触发计时器时,将从过滤器控件中收集过滤器数据,并将查询字符串输入到gridview iframe,如下所示:

var URL = "/mypage/gridview.aspx";
var dest = URL + '?' + getFilterData();
var frame = $('#gridiframe');
$.ajax({
    type: "HEAD",
    async: true,
    url: dest
}).success(function () {
    frame.attr('src', dest);
})
.error(loadError);

My conundrum is this: the gridview can be very costly to render. It performs a HUGE database trip and this method is causing the page to be rendered twice. The first time, the client just looks at the header to make sure the user is authenticated (page returns HTTP unauthorized if session has timed out) and that all the parameters are in a good format. But I don't want to change the iframe source to show an error message, I just want to call loadError which basically just notifies the user what went wrong.

我的难题是:gridview的渲染成本非常高。它执行巨大的数据库旅行,此方法导致页面呈现两次。第一次,客户端只查看标题以确保用户已经过身份验证(如果会话超时,页面将返回HTTP,并且所有参数都处于良好格式)。但我不想更改iframe源以显示错误消息,我只想调用loadError,它基本上只是通知用户出了什么问题。

Is there anything I can do with the client code to populate my iframe in only one exchange with the server?

有什么我可以用客户端代码在与服务器的一次交换中填充我的iframe吗?

edit: thanks all for your input. At the end of the day, I hate webforms. End of story.

编辑:感谢大家的投入。在一天结束时,我讨厌webforms。故事结局。

3 个解决方案

#1


4  

Instead of querying the iframe's source URL in the ajax query, query a different endpoint that doesn't run the same DB query. You said it does two things, 1 validate the user's login token is still valid and 2 that the filter parameters are valid. Neither of those validation steps require running the query on the database that get the full query results. So, create a new API endpoint that does your basic validation, and if that returns a success message, then set the iframe source to what you want.

不是在ajax查询中查询iframe的源URL,而是查询不运行相同数据库查询的其他端点。你说它做了两件事,1验证用户的登录令牌仍然有效,2验证过滤器参数是有效的。这些验证步骤都不需要在获取完整查询结果的数据库上运行查询。因此,创建一个新的API端点进行基本验证,如果返回成功消息,则将iframe源设置为您想要的。

Another option is to return a HTML fragment, rather than a full HTML page, from gridview.aspx. Then your AJAX can replace the contents of a div with the HTML result if successful, rather than setting the iframe src, while still allowing you to handle errors.

另一种选择是从gridview.aspx返回HTML片段,而不是完整的HTML页面。然后,如果成功,您的AJAX可以用HTML结果替换div的内容,而不是设置iframe src,同时仍允许您处理错误。

A more trendy option (not saying it's better or worse, but certainly more aligned with the current web development industry) is to change gridview.aspx to a web service/api that returns the data in simplified json, then use a javascript framework, or template engine to generate the html table on the client itself.

一个更时髦的选择(不是说它更好或更糟,但肯定更符合当前的Web开发行业)是将gridview.aspx更改为以简化的json返回数据的web服务/ api,然后使用javascript框架,或者模板引擎在客户端本身生成html表。

#2


4  

Maybe I'm over-simplifying things, but couldn't you just use a QueryString parameter in the second request?

也许我过度简化了事情,但你不能在第二个请求中使用QueryString参数吗?

$.ajax({
    type: "HEAD",
    async: true,
    url: dest
}).success(function () {
    frame.attr('src', dest + '&getGrid=true');
})

And then on the aspx page check if the QueryString is present.

然后在aspx页面上检查QueryString是否存在。

protected void Page_Load(object sender, EventArgs e)
{
    //validate user always

    if (Request.QueryString["getGrid"] != null)
    {
        //rebuild grid 
    }
}

#3


2  

Instead of an iFrame you can a normal <div> and load only the gridView from another page as follows:

您可以使用普通的

而不是iFrame,而只从另一个页面加载gridView,如下所示:

First, Wrap the gridView around a container in the other page Something like

首先,将gridView包装在另一个页面中的容器周围

<div id='grid-wrapper'><!-- GridView here --></div>

Then use your AJAX code like this to retrieve only the grid:

然后使用这样的AJAX代码只检索网格:

var URL = "/mypage/gridview.aspx";
var dest = URL + '?' + getFilterData();
var div = $('#divId');
$.ajax({
    type: "HEAD",
    async: true,
    url: dest
}).success(function (res) {
    div.html($('#grid-wrapper',$(res)).html); //this gets only the contents of grid-wrapper and not the whole page.
})

#1


4  

Instead of querying the iframe's source URL in the ajax query, query a different endpoint that doesn't run the same DB query. You said it does two things, 1 validate the user's login token is still valid and 2 that the filter parameters are valid. Neither of those validation steps require running the query on the database that get the full query results. So, create a new API endpoint that does your basic validation, and if that returns a success message, then set the iframe source to what you want.

不是在ajax查询中查询iframe的源URL,而是查询不运行相同数据库查询的其他端点。你说它做了两件事,1验证用户的登录令牌仍然有效,2验证过滤器参数是有效的。这些验证步骤都不需要在获取完整查询结果的数据库上运行查询。因此,创建一个新的API端点进行基本验证,如果返回成功消息,则将iframe源设置为您想要的。

Another option is to return a HTML fragment, rather than a full HTML page, from gridview.aspx. Then your AJAX can replace the contents of a div with the HTML result if successful, rather than setting the iframe src, while still allowing you to handle errors.

另一种选择是从gridview.aspx返回HTML片段,而不是完整的HTML页面。然后,如果成功,您的AJAX可以用HTML结果替换div的内容,而不是设置iframe src,同时仍允许您处理错误。

A more trendy option (not saying it's better or worse, but certainly more aligned with the current web development industry) is to change gridview.aspx to a web service/api that returns the data in simplified json, then use a javascript framework, or template engine to generate the html table on the client itself.

一个更时髦的选择(不是说它更好或更糟,但肯定更符合当前的Web开发行业)是将gridview.aspx更改为以简化的json返回数据的web服务/ api,然后使用javascript框架,或者模板引擎在客户端本身生成html表。

#2


4  

Maybe I'm over-simplifying things, but couldn't you just use a QueryString parameter in the second request?

也许我过度简化了事情,但你不能在第二个请求中使用QueryString参数吗?

$.ajax({
    type: "HEAD",
    async: true,
    url: dest
}).success(function () {
    frame.attr('src', dest + '&getGrid=true');
})

And then on the aspx page check if the QueryString is present.

然后在aspx页面上检查QueryString是否存在。

protected void Page_Load(object sender, EventArgs e)
{
    //validate user always

    if (Request.QueryString["getGrid"] != null)
    {
        //rebuild grid 
    }
}

#3


2  

Instead of an iFrame you can a normal <div> and load only the gridView from another page as follows:

您可以使用普通的

而不是iFrame,而只从另一个页面加载gridView,如下所示:

First, Wrap the gridView around a container in the other page Something like

首先,将gridView包装在另一个页面中的容器周围

<div id='grid-wrapper'><!-- GridView here --></div>

Then use your AJAX code like this to retrieve only the grid:

然后使用这样的AJAX代码只检索网格:

var URL = "/mypage/gridview.aspx";
var dest = URL + '?' + getFilterData();
var div = $('#divId');
$.ajax({
    type: "HEAD",
    async: true,
    url: dest
}).success(function (res) {
    div.html($('#grid-wrapper',$(res)).html); //this gets only the contents of grid-wrapper and not the whole page.
})