Asp.Net单一控制渲染的AJAX调用 [英] Asp.Net single control render for AJAX calls
问题描述
我想实现类似的东西<一个href="http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx">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://本地主机:999 / MyApp的/ mypage.aspx
不过,我得到: 的http://本地主机:999 / mypage.aspx
失踪MyApp的......
Missing 'MyApp'...
我认为这个问题是在创建用于加载控件的页:
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服务,返回阿贾克斯部分呈现的控制:
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
和它的罚款,但NavigateUrl被解析为
and it's fine, but the NavigateUrl is resolved as
的http://本地主机:999 / mypage.aspx
不失/ MyApp的/。 当然,如果我把,而不是在WS使用的pageHolder比如我的ascx在真实的页面,一切工作正常。
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)
我得到的网页的正确网址:
的http://本地主机: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?
推荐答案
问题是,页面级不intented的实例就是这样。如果我们火了反射,我们很快就会看到,Asp.Net内部实例化一个Page类的返回它作为一个的IHttpHandler后设置的一个重要属性。你将不得不设置鸭prelativeTemplateSourceDirectory。这是存在于Control类的属性,并在内部它设置这是由例如超链接的链接解析正确的URL为〜的TemplateControlVirtualDirectory属性。
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方法之前,因为鸭prelativeTemplateSourceDirectory值上通过你的主人控件创建控件通过。
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.
如何获取正确的值在你的属性设置?使用静态AppDomainAppVirtualPath上的httpRuntime类。洙,概括起来讲...这应该工作;
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();
}
这篇关于Asp.Net单一控制渲染的AJAX调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!