Asp.Net AJAX调用的单控制呈现
我试图实现类似于this或this的东西。Asp.Net AJAX调用的单控制呈现
我创建了一个用户控件,一个web服务和一个web方法来返回控件的呈现html,通过jQuery执行ajax调用。
所有的工作都很好,但是如果我在使用相对路径的用户控件(在我的情况下是一个带有NavigateUrl =“〜/ mypage.aspx”的HyperLink)的东西放在我的开发服务器的相对路径的解析失败。
我期待: http://localhost:999/MyApp/mypage.aspx
,但我得到: http://localhost:999/mypage.aspx
缺少 'MyApp的' ......
我认为这个问题是用来加载生成页的控制:
Page page = new Page();
Control control = page.LoadControl(userControlVirtualPath);
page.Controls.Add(control);
...
但我不明白为什么....
编辑 只是为了清楚起见
我的用户控件位于~/ascx/mycontrol.ascx
,并包含一个非常简单的结构:由现在只是一个像"~/mypage.aspx"
与NavigateUrl超链接。 而“mypage.aspx”确实位于根目录下。
然后我做了一个Web服务,返回阿贾克斯部分呈现的控制:
[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开发的服务器执行的项目,我的应用程序的根是
和它的罚款,但NavigateUrl被解析为
http://localhost:999/mypage.aspx
lost/MyApp /。 当然,如果我把我的ascx放在一个真实的页面中,而不是ws中使用的pageHolder实例,所有工作都正常。
另一个奇怪的事情是,如果我设置hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx")
我得到的页面的正确网址: http://localhost:999/MyApp/mypage.aspx
而现在我会做到这一点,但我想明白为什么它不工作正常的方式。 有什么想法?
问题是,页面类不是像这样实例化的。如果我们启动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();
}
太好了,我喜欢这种方式! – tanathos 2010-10-21 12:01:48
tildy pust是应用程序根目录中的路径,因此它会生成您所看到的结果。您将要使用:
NavigateUrl="./whatever.aspx"
编辑:
这里是一个链接,也可能证明是有益的?http://msdn.microsoft.com/en-us/library/ms178116.aspx
但我想要我的网址上的应用程序路径,我需要它为我的本地开发服务器。 url http:// localhost:999/mypage.aspx根本不存在。如果我把ascx放在页面上,所有的相对路径都被解析为http:// localhost:999/MyApp/something.something ...并且它是正确的。 – tanathos 2010-06-30 16:29:17
你可以为ascx的页面注册显示标记,也可以简单地解释你的站点结构(页面驻留在哪里,控件位于何处)?我有一种感觉,这是因为控件/页面在不同的目录中。 – AGoodDisplayName 2010-06-30 16:38:12
我发现/ MyApp/root会导致各种问题。它并没有真正回答你'为什么不能正常工作'的问题,但是你是否意识到你可以摆脱/ MyApp /并将你的网站托管在http:/ localhost/...?
只需在网站属性中将“虚拟路径”设置为“/”即可。
这清除了所有的东西,除非你正试图在开发PC上同时托管多个应用程序。
问题是我有很多应用程序配置为开发...现在我已经绕过这个问题使用Page.ResolveUrl(“〜/ mypage.aspx”),但我真的想明白为什么:) – tanathos 2010-07-09 16:25:03
可能是因为新的页面对象没有“MyApp”作为根目录,所以它被默认解析为服务器根目录。
我的问题是它为什么与Page.ResolveUrl(...)
一起使用。
也许ResolveUrl
做了一些关于用户控件的位置的调查,并基于此来解决。
奇怪,我重新创建了这个例子。该超链接对〜/ Default.aspx的给定导航网址呈现为<a id="ctl00_hlRawr" href="Default.aspx"></a>
。我的猜测是它与RequestMethod有关。在常规页面上是“GET”,但在web服务调用中它是“POST”。
我无法通过hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx")
重新创建结果该控件总是呈现为给定虚拟路径的<a id="ctl00_hlRawr" href="Default.aspx"></a>
。 (Page.ResolveUrl给我“〜/ Default.aspx”)
我会建议做这样的事情,以避免在未来的麻烦。
protected void Page_Load(object sender, EventArgs e)
{
hlRawr.NavigateUrl = FullyQualifiedApplicationPath + "/Default.aspx";
}
public static string FullyQualifiedApplicationPath
{
get
{
//Return variable declaration
string appPath = null;
//Getting the current context of HTTP request
HttpContext context = HttpContext.Current;
//Checking the current context content
if (context != null)
{
//Formatting the fully qualified website url/name
appPath = string.Format("{0}://{1}{2}{3}",
context.Request.Url.Scheme,
context.Request.Url.Host,
(context.Request.Url.Port == 80 ? string.Empty : ":" + context.Request.Url.Port),
context.Request.ApplicationPath);
}
return appPath;
}
}
问候,
这是很难告诉你正在努力实现,而无需缴纳,实际上将URL超链接的线什么的,但我想我明白你的目录结构。
但是,我从来没有遇到过使用ResolveUrl()方法无法以某种方式解决的情况。建议不要在生产中使用的临时路径的字符串解析,因为它会增加项目的复杂性。
此代码将在从页面继承的任何对象解决(包括用户控件):
Page page = (Page)Context.Handler;
string Url = page.ResolveUrl("~/Anything.aspx");
你可以尝试的另一件事情是这样的:
Me.Parent.ResolveUrl("~/Anything.aspx");
如果这些都不是工作,你可能想检查你的IIS设置,以确保你的网站被配置为一个应用程序。
用户控件不会从页面中插入!并且在页面对象上调用父对象会自动返回,所以不需要。 – 2010-10-19 20:54:54
@BurningIce - 感谢您的发现。我打算使用usercontrol的Parent。我用更正更新了代码示例。 – NightOwl888 2010-10-20 06:22:47
,但仍然失败,因为然后处理程序的请求不会是类型页面,但最有可能的WebServiceHandler,因为文件tanathos请求最有可能具有扩展名.asmx或.svc(不.aspx)。 – 2010-10-20 16:08:37
在页面/控件生命周期中,你会调用'hl.NavigateUrl = Page.ResolveUrl(“〜/ mypage.aspx”)'?在这之前,你是否在代码中的同一个地方运行'hl.NavigateUrl =“〜/ mypage.aspx”'? – awe 2010-09-15 07:10:08