用于 AJAX 调用的 Asp.Net 单一控件渲染 [英] Asp.Net single control render for AJAX calls

查看:35
本文介绍了用于 AJAX 调用的 Asp.Net 单一控件渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现类似于 this这个.

I'm trying to implement something similar to this or this.

我创建了一个用户控件、一个 web 服务和一个 web 方法来返回控件的渲染 html,通过 jQuery 执行 ajax 调用.

I've created a user control, a web service and a web method to return the rendered html of the control, executing the ajax calls via jQuery.

一切正常,但是如果我在使用相对路径的用户控件中放置一些东西(在我的例子中是带有 NavigateUrl="~/mypage.aspx" 的超链接),相对路径的解析在我的开发服务器中失败.

All works fine, but if I put something in the user control that uses a relative path (in my case an HyperLink with NavigateUrl="~/mypage.aspx") the resolution of relative path fails in my developing server.

我期待:http://localhost:999/MyApp/mypage.aspx

但我得到:http://localhost:999/mypage.aspx

缺少我的应用"...

我认为问题在于用于加载控件的页面的创建:

I think the problem is on the creation of the Page used to load the control:

Page page = new Page();
Control control = page.LoadControl(userControlVirtualPath);
page.Controls.Add(control);
...

但我不知道为什么....

But I can't figure out why....

编辑只是为了清楚

我的用户控件位于 ~/ascx/mycontrol.ascx并且包含一个非常简单的结构:现在只是一个带有 NavigateUrl 的超链接,例如 "~/mypage.aspx".而mypage.aspx"确实驻留在根目录中.

My user control is located at ~/ascx/mycontrol.ascx and contains a really simple structure: by now just an hyperlink with NavigateUrl like "~/mypage.aspx". And "mypage.aspx" really resides on the root.

然后我做了一个web服务来将部分渲染的控件返回给ajax:

Then I've made up a web service to return to ajax the partial rendered control:

[ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class wsAsynch : System.Web.Services.WebService
{
    [WebMethod(EnableSession = true)]
    public string GetControl(int parma1, int param2)
    {
        /* ...do some stuff with params... */
        Page pageHolder = new Page();

        UserControl viewControl = (UserControl)pageHolder.LoadControl("~/ascx/mycontrol.ascx");
        Type viewControlType = viewControl.GetType();

        /* ...set control properties with reflection... */

        pageHolder.Controls.Add(viewControl);
        StringWriter output = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, output, false);

        return output.ToString();
    }
}

html正确渲染,但超链接的NavigateUrl中的相对路径解析错误,因为当我从VS2008的开发服务器执行项目时,我的应用程序的根是

The html is correctly rendered, but the relative path in the NavigateUrl of hyperlink is incorrectly resolved, because when I execute the project from developing server of VS2008, the root of my application is

http://localhost:999/MyApp/

没关系,但是 NavigateUrl 被解析为

and it's fine, but the NavigateUrl is resolved as

http://localhost:999/mypage.aspx

失去/MyApp/.当然,如果我将我的 ascx 放在一个真实的页面中,而不是 ws 中使用的 pageHolder 实例,一切正常.

losing /MyApp/ . Of Course if I put my ascx in a real page, instead of the pageHolder instance used in the ws, all works fine.

另一个奇怪的事情是,如果我设置 hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx") 我会得到正确的页面 url:http://localhost:999/MyApp/mypage.aspx

Another strange thing is that if I set the hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx") I get the correct url of the page: http://localhost:999/MyApp/mypage.aspx

现在我会这样做,但我会明白为什么它不能以正常方式工作.有什么想法吗?

And by now I'll do that, but I would understand WHY it doesn't work in the normal way. Any idea?

推荐答案

问题是 Page-class 并不是为了像那样实例化.如果我们启动 Reflector,我们将很快看到 Asp.Net 内部在实例化 Page 类并将其作为 IHttpHandler 返回后设置了一个重要属性.您必须设置 AppRelativeTemplateSourceDirectory.这是一个存在于 Control 类中的属性,它在内部设置 TemplateControlVirtualDirectory 属性,例如 HyperLink 使用该属性来解析链接中~"的正确 url.

The problem is that the Page-class is not intented for instantiating just like that. If we fire up Reflector we'll quickly see that the Asp.Net internals sets an important property after instantiating a Page class an returning it as a IHttpHandler. You would have to set AppRelativeTemplateSourceDirectory. This is a property that exists on the Control class and internally it sets the TemplateControlVirtualDirectory property which is used by for instance HyperLink to resolve the correct url for "~" in a link.

在调用 LoadControl 方法之前设置此值很重要,因为 AppRelativeTemplateSourceDirectory 的值会传递给主"控件创建的控件.

Its important that you set this value before calling the LoadControl method, since the value of AppRelativeTemplateSourceDirectory is passed on to the controls created by your "master" control.

如何获得正确的值以设置您的属性?在 HttpRuntime 类上使用静态 AppDomainAppVirtualPath.Soo,总结一下……这应该可行;

How to obtain the correct value to set on your property? Use the static AppDomainAppVirtualPath on the HttpRuntime class. Soo, to sum it up... this should work;

[WebMethod(EnableSession = true)]
public string GetControl(int parma1, int param2)
{
    /* ...do some stuff with params... */
    var pageHolder = new Page() { AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath };

    var viewControl = (UserControl)pageHolder.LoadControl("~/ascx/mycontrol.ascx");
    var viewControlType = viewControl.GetType();

    /* ...set control properties with reflection... */

    pageHolder.Controls.Add(viewControl);
    var output = new StringWriter();
    HttpContext.Current.Server.Execute(pageHolder, output, false);

    return output.ToString();
}

这篇关于用于 AJAX 调用的 Asp.Net 单一控件渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆