一尘不染

用于AJAX调用的Asp.Net单个控件呈现

ajax

我正在尝试实现类似于thisthis的东西。

我创建了一个用户控件,一个Web服务和一个Web方法来返回控件的呈现的html,并通过jQuery执行ajax调用。

一切正常,但是如果我在用户控件中放置了使用相对路径的内容(在我的情况下为带有NavigateUrl =“〜/
mypage.aspx”的HyperLink),则相对路径的解析在我的开发服务器中将失败。

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

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

缺少“ MyApp” …

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

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

但我不知道为什么…

编辑 只是为了清楚

我的用户控件位于,~/ascx/mycontrol.ascx
并包含一个非常简单的结构:到目前为止,仅带有NavigateUrl之类的超链接"~/mypage.aspx"。而“
mypage.aspx”实际上位于根目录上。

然后,我组成了一个Web服务,以将部分呈现的控件返回给ajax:

[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的开发服务器执行项目时,我的应用程序的根目录是

http:// localhost:999 / MyApp /

很好,但是NavigateUrl解析为

http:// localhost:999 / mypage.aspx

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

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

到现在为止,我会这样做,但是我会明白为什么它无法正常运行。任何想法?


阅读 207

收藏
2020-07-26

共1个答案

一尘不染

问题在于,Page类并非旨在像这样进行实例化。如果启动Reflector,我们将很快看到在实例化Page类并将其作为IHttpHandler返回之后,Asp.Net内部设置了一个重要的属性。您将必须设置AppRelativeTemplateSourceDirectory。这是Control类上存在的一个属性,并且在内部设置了TemplateControlVirtualDirectory属性,HyperLink例如使用该属性来解析链接中“〜”的正确URL。

请务必在调用LoadControl方法之前设置此值,因为AppRelativeTemplateSourceDirectory的值会传递到“主”控件创建的控件上。

如何获得正确的值来设置您的财产?在HttpRuntime类上使用静态AppDomainAppVirtualPath。总结一下,这应该起作用。

[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();
}
2020-07-26