Hyperlink relative to current URL not path of user control - asp.net

I have a page on my site, for purposes of this example lets say http://myhost/Pages/Default.aspx. On Default.aspx I have a user control called MyControl.ascx which lives in /Controls/MyControl.ascx. So the tree looks something like this
Root
Pages
Default.aspx
Controls
MyControl.ascx
Whenever I place a HyperLink control on MyControl.ascx and specify a NavigateUrl, this path is relative to the control, not the URL of the page. So for instance if in NavigateUrl I specified "AboutMe.aspx", the URL would be rendered as http://myhost/Controls/AboutMe.aspx instead of http://myhost/Pages/AboutMe.aspx. Is there any way I can make this relative to the page URL? I've tried the solution here: Relative path from an ASP.NET user control NavigateUrl but it didn't work for me.
Edit
To clarify, I'd like this to be generic enough so that if I didn't know what the path was the solution would work. So I don't really want to harcode "~/Pages/Default.aspx" in the NavigateUrl

You have a bunch of options:
You could hardcode the Url using the ~ operator which give you the root and then define it from there like: ~/Pages/AboutMe.aspx. Keep in mind that the ~ operator is recognized only for server controls and in server code.
You could also use the .. to get you to where you want as it will navigate back up the folder structure like: ../Pages/AboutMe.aspx
You could create a helper methods to return you a valid root to your Pages folder, Images, Javascript, etc...
The HttpRequest.ApplicationPath will get your the virtual application's root path on the server which you can use to build off.
For more information on Pathing options you should read this article on MSDN:
ASP.NET Web Project Paths
EDIT: Based on your edit to your question, you should then pass in the relative URL into you user control via a property. Let the page that uses the control define the relative path to the resource it will require.

The best way to achieve this is to use
string.Format("{0}", Page.Request.Url.PathAndQuery);
in NavigateUrl property

Just in case anyone else stumbles across this as I did...
In the code behind, I set the NavigateUrl to:
link.NavigateUrl = Page.ResolveUrl("aboutus.aspx");

How do you set the NavigateUrl of the hyperlink? If I set it using the ~ character, then it works as expected:
MyControl.ascx
<asp:HyperLink runat="server" NavigateUrl="~/Pages/Default.aspx" ... >

Simpler than that. Just change the usercontrol's AppRelativeTemplateSourceDirectory property to the value of the same property of the parent Page.
protected override void OnInit(EventArgs e)
{
AppRelativeTemplateSourceDirectory = Page.AppRelativeTemplateSourceDirectory;
base.OnInit(e);
}
then all relative path in user control will be if there was in page.

Related

Getting hidden field value from content-page after cross-page post

I have the following situation:
Page1.aspx is based on a master page and has a hidden field called "hdFlotaID" in it. On the same page I have a button for which I set PostBackUrl="Page2.aspx". When I click the buton, the Page2 is loaded but I can't get the hidden field. I tried both (as I saw on msdn or other posts):
this.PreviousPage.Controls[0].FindControl("hdFlotaID")
and
this.PreviousPage.FindControl("hdFlotaID")
but they return null.
This.PreviousPage returns a value, but Controls[0] of that value seems to return the masterpage and I want the content page.
I also checked and the hidden field has runat server value and ClientID mode is set to static (I even checked the generated HTML and the ID is correct)
Can you please help me! Thank you
SOLUTION: Ok,so based on your help I got it to work like this
this.PreviousPage.Controls[0].FindControl("CPH").FindControl("hdFlotaID")
where CPH is the ID of the ContentPlaceHolder from the master page.
Also the ideea with the public property is very good allthough in my case adding the PreviousPageType directive was giving me some errors about namespaces. If I removed the directive and cast it in codebehind it works fine.
Thank you all very much
FindControl searches only one level i.e. top level container and all the controls of your content page are not directly in Master control collection rather inside master's content control collection.
To achieve this
1) you need to write a recursive version of FindControl. try like this (did not tested it):
((Page1)this.PreviousPage).FindControl("hdFlotaID")
or
2) Typecast the previous page to the type of page it is. Then you can access controls.
Set up a property in page1.aspx that returns value of hidden field using this.Page.MasterPage.FindControl("hdFlotaID"). In Page2.aspx, add "PreviousPageType" tag in ASPX file. This way you can access previos page properties in a typesafe way e.g. this.PreviousPage.hdFlotaID_property

Accessing app setting from aspx and add concatenated text

I've got a project where I'm tasked with changing hard-coded domain references from one domain to another in a group of legacy C#/VB web projects. I want to parameterize the domains as much as possible instead of just replacing with a different hard-coded value. The problem is that there are over 800 of these references in about 30 different solutions, so creating variables in each code-behind to bind to would take forever.
I have added the new domains to the appSettings section of the web.config file, and this works:
<asp:HyperLink Text="Link" NavigateUrl="<%$appSettings:DomainX %>" runat="server" />
But I need to be able to do something like this:
<asp:HyperLink Text="Link" NavigateUrl="<%$appSettings:DomainX %>/newPage.aspx" runat="server" />
But when I add the "/newPage.aspx" the page doesn't compile anymore. I don't really care if this is done with an asp:HyperLink tag or just a tag.
Any ideas on how I can accomplish this?
Thanks.
I think you have two options. The easiest is to just use a plain old anchor tag, if you're not doing anything with the HyperLink server side:
Link
Alternatively, you could set the NavigateUrl in the Page_Load, since <%= will not work properly within the HyperLink server tag:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
link1.NavigateUrl = string.Concat("http://",
ConfigurationManager.AppSettings["DomainX"], "/newPage.aspx");
}
You could also see if you can make a custom binding, something like $myBinding:DomainX, but I don't know if that's possible off the top of my head (I would assume it is though).
EDIT
That $appSettings:DomainX code is called an ASP.NET Expression, and can you can create custom expressions. This post from Phil Haack covers how to set them up, in case you are interested.
How about something along the lines of:
<%=ConfigurationManager.AppSettings["DomainX"].ToString() + "/newPage.aspx" %>
I would go with one of two different approaches that would save you the need to change the NavigateUrl in the .aspx itself.
One option is to inherit from HyperLink class and overriding the NavigateUrl property, adding the ConfigurationManager.AppSettings["DomainX"] in the getter method. Having this, just change <asp:HyperLink ... to <UC:MyLink ...
Second option is adding small function to each page (can be in one shared place and just called from each page) that will iterate over all the hyperlinks controls and dynamically add the domain. To find all controls of certain type you can use such code for example.

Absolute URL Cookieless

Is there some method in asp.net for getting an absolute url with cookieless session?
UPDATE: I need create other new URL. It is not requested URL.
I´m using Response.ApplyAppPathModifier for getting relative URL with cookie session.
Thx in advance,
I tried Request.RawUrl and Request.Url (and its properties in the Immediate window).
None did show the extra attribute the setting (web.config):
<sesionState cookieless="true" />
makes in the url.
Example
http://localhost:2677/WebSite1/(S(3abhbgwjg33aqrt3uat2kh4d))/cookielesssessiondetection.aspx
However if you're after that part, 3abhbgwjg33aqrt3uat2kh4d, you can get it via:
Session.SessionID
Update after the updated question:
I put in my test application a Hyperlink control on the page. In code behind, Page_Load, I added:
HyperLink1.NavigateUrl = Response.ApplyAppPathModifier("About.aspx");
When I run that page then the url to About.aspx gets set with the cookieless session part included.
When I check the source of the rendered html in my browser I see this:
<a id="HyperLink1" href="/WebSite1/(S(3tzgdnmhwxmxqer10d11auuq))/About.aspx">HyperLink</a>
Did you try Request.Url.ToString(). It should work for you.
If you needed was the url of another page on your site then you can proceed like this...
String url = new Uri(Context.Request.Url, ResolveUrl("~/ABC.aspx")).ToString )
We also have something like Request.Url.AbsoluteUri
I hope One of the above should work for you.

asp.net and Ajax

I am using the following JavaScript code to refresh another page
window.opener.location.replace(url)
The problem is when entering the URL, do not find the page as the page is located in the root and this calling code is placed in a page inside another folder. How do I specify the path to point to the root, which is where the page is located? I have tried many things, but none worked:
//page.aspx
../page.aspx
~/page.aspx
page.aspx
/page.aspx
....
This form should work:
window.opener.location = url;
The replace method replaces a match in the current URL with another string, but it won't work with just one parameter. At any rate, it is not necessary to specify the full URL, you can only specify the partial path such as:
../page.htm
You would have to give exact path

Passing value through querstring without showing the destination page in the URL with ASP.NET web form

I have a small web app being written in ASP.NET, VB.NET , .NET 3.5
I pass a value from default.aspx to demo.aspx using query string. When Go button is clicked the URL will be like this : localhost/demo.aspx?id=4
But I want URL to be sth like this when Go button is clicked : localhost/?id=4 and the id value is passed to demo.aspx so the expected result can be shown. How to get this done if possible without using the routing technique.
This will work only if the web server considers demo.aspx to be the default document. When you load a page without stating the page name (such as you localhost/?id=4 example), the web server will locate a file with a pre-defined name and use it as the default document. Often this file is called default.aspx (or .asp, .htm, .html, .php or something like that). So if you want to load any other page you will need to either state the name, or use URL rewriting techniques.
Modify your go button to link button and set herf = "?id=[id]"
Modify Page_Load event of Default.aspx by using the following code.
public Page_Load(object sender,EventArg e)
{
if(!string.IsNullOrEmpty(Request["id"]))
{
// Using Server.Transfer() function to call Demo.aspx page.
// Client still see "localhost/?id=[id]" at address bar.
Server.Transfer("Demo.aspx?id=" + Request["id"]);
}
}
Something like this?
protected void btnGo_Click (Object sender, EventArgs e)
{
Response.Redirect("localhost/?" + Request.QueryString);
}
Not sure when you want the url to change? Not sure what the routing technique is either. Sorry.
if you want it to work with postbacks, you still need to make sure the webserver is configured with a default document like default.aspx.
in 3.5 sp1 MS finally allows us to set the action attribute of the form.
so on page init you can explicitly set it now
Form1.Action = "/mydirectory/"
Caveat: Some versions of IIS do not allow posting to a directory. (XP IIS for example)

Resources