Razor Page - How to redirect to another folder's page using asp-for tag helper - asp.net

I've been having issues with this but I think is simple.
asp.net core 2.0 Razor Pages
I have a Users/index page and I added a link to take me to the child records under Entries Folder.
Structure is like
Pages
/Users
/Entries
Under /Pages/Users/index.cshtml
<a asp-page="./Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="#item.Id">Details</a>|
<a asp-page="~/Pages/Entries/" asp-route-id="#item.Id">Enter Child Records</a>
However, on the browser, looks like is not rendering the correct link. It staying under the default page.
I tried asp-page="../Entries/" and other combinations with no luck.

Can't believe this but this works.
<a asp-page="../Entries/Index" asp-route-id="#item.Id">test</a>

I think your own answer might add confusions to others. First of all, you're talking about LINKs to another page, not redirect to another page. Razor Pages have a designated function for page redirections.
About the asp-page tag helper, it's interpreted by the code-behind engine (e.g. C# syntax) and so the "~" doesn't work. Basically, asp-page is expecting a name. In your own examples:
<a asp-page="./Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="#item.Id">Details</a>|
will work, but they should be shortened as:
<a asp-page="Edit" ...>Edit</a> |
<a asp-page="Details" ...>Details</a>|
because they are in the same folder as your /Users/Index page. As you know the "./" part just means going up one level to your parent folder and so it's redundant. You don't want to instruct your engine to go up one level and then come down again to the same folder immediately.
When you need to switch to another containing folder, going up two levels and specify the new folder name. So, the "../NewFolder" works.
If it is at the web site root level, you can use the root syntax directly for faster routing. So both of these work the same if AnotherFolder is under root:
<a asp-page="../AnotherFolder/Index" ...>test</a>
<a asp-page="/AnotherFolder/Index" ...>test</a>
The asp-page tag helper is expecting a real page name at the last part and hence the quoted text must be ended with a page name. You cannot use asp-page="/Entries/" as in HTML URLs and expect the engine to default to Index page for you.
Lastly, to cover redirecting pages, code-behind has a function called return RedirectToPage(string pageName, ...), and its first parameter uses the same page routing syntax as the asp-page tag helper described above.
There is also a Redirect() function that works with pages outside your Razor Pages system, which can take any URLs as your browser or HTML code do. That's another story.

Related

Remove link to document caching in ASP.NET

I'm trying to append DateTime.Now.Ticks to my link to stop it from caching as I'll be replacing it often. The problem I'm having when I do the code below is that it's adding a Content path in the url.
The original link was:
<a target="_blank" href="~/Documents/Data/Acct/MyDocument.pdf">Document</a>
This obviously caches the file on the browser so when I overwrite MyDocument.pdf the users don't see that unless they Ctrl-F5. So I changed it to the following:
<a target="_blank" href=#string.Format("{0}?t={1}", "~/Documents/Data/Acct/MyDocument.pdf", DateTime.Now.Ticks)>Document</a>
This produces a link that looks like: Content/~Documents/Data/Acct/MyDocument.pdf" which obviously doesn't exist because it's adding in Content and keeps the ~. If I remove the ~ I still get Content/Documents/Data/Acct/myDocument.pdf. How do I stop .NET from adding this Content/ to my link?
To add, the page that this link is in, is inside a folder called Views/Content. So I guess that's where it's being called from, but the ~ I assume should go up a level but it's not.
<a target="_blank" href=#string.Format("{0}?t={1}", "../Documents/Data/Acct/MyDocument.pdf", DateTime.Now.Ticks)>Document</a>
If you want to go up a level in your Url use ../ should get rid of the Content

Foundation: Root variable in links not working for pages in subdirectories

On the Foundation site I am working on, there is a dropdown topbar in a navigation partial that populates its links from several YML files in src/data (one per dropdown category). Each entry looks something like this:
link:
text: "Example Link"
url: "beta/page2.html"
external: false
The piece of the partial that generates each menu entry is as follows:
{{#each category}}
<li><a href="{{#unless external}}{{root}}{{/unless}}{{url}}" {{#if external}}target="_blank"{{/if}}>{{text}}</a></li>
{{/each}}
The goal is for the link to be relative to the site's root if external is false, and used as-is (and open a new tab) if external is true.
The problem is that internal links don't seem to generate properly when the page I am navigating from is in a subdirectory. For example, if I am on example.com/alpha/page1.html, the menu link above points to example.com/alpha/beta/page2.html instead of example.com/beta/page2.html.
How can I change my code to properly generate the links for the pages?
I figured out the issue. Inside the {{#each}} block, the Handlebars context changes, making variables like {{root}} only accessible through the parent context. The issue can be fixed by replacing {{root}} with {{../root}}.
From the Handlebars documentation:
The exact value that ../ will resolve to varies based on the helper that is calling the block. Using ../ is only necessary when context changes, so children of helpers such as each would require the use of ../ while children of helpers such as if do not.

How to find page in folder when using master page asp.net

When my pages are in the main level of the solution, the menu item href can find the content pages. When I put the content pages in a subfolder and change the href path respectively it cannot find the page. This seems to only be a problem with MasterPages. Am I missing something here? I get the error
Server Error in '/' Application The resource cannot be found HTTP 404.
Requested URL: /Pages/Pages/Items.aspx
Why does it add another /Pages in front of my path?
Solution
Project
+Images
-Pages
Items.aspx
Library.aspx
+Styles
Default.aspx
Site.Master
MasterPage
<div id="tabdiv" class="tabdiv">
<ul id="tabmenu" class="tabmenu">
<li>Items</li>
<li>Library</li>
</ul>
</div>
<div id="main" class="main">
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
Short answer, use an absolute path (to the root of your site) or use ~/ to relate all pages back to the site root (latter being more secure and robust between server location changes).
Reasoning?
When you're within the root (/) linking to Pages/Items.aspx combines these two: /Pages/Items.aspx.
When you're already in Pages/ you're now re-citing the same directory Pages/Items.aspx so you're getting a combined value of /Pages/Pages/Items.aspx.
When you want to link to items, have a look at the Control.ResolveUrl method. e.g.
Items
Now, no matter what page that link is embedded it, it still will provide an absolute path to that resource (in this case, Items.aspx).
try like this
<li>Items</li>
<li>Library</li>
Use thge above
Items
Remove the Pages from the href. The master page is a wrapper for the .aspx pages' content, but you should use the relative path to the .aspx page when you provide the links inside the master page (given that all your pages are inside the Pages folder):
<li>Items</li>
<li>Library</li>
Another option would be to prefix with /, which will render the link by using the root-relative link/root link/web-root relative link:
<li>Items</li>
<li>Library</li>
If your tag is "a href" you must put runat = "server" with their respective id = "lnkItem" then the code of the page from the server side you should write:
lnkItem.HRef = ResolveUrl("~/Pages/Items.aspx");
If you are calling to another site you can use 'ResolveUrl':
Response.Redirect(ResolveUrl("~/Pages/Items.aspx"));
Give a path like this.Include your Domain name.
<li>Items</li>
Or
You should use XML file or website path file.

redirect to a page is not working properly in asp .net which is inside sub folder

I have sub folders says X,Y,Z. I'm making menu list dynamically using 'ul', 'li' tags based on user rights. Inside 'li' tag i have 'a href="#"' tag. The tag 'a' filled from database dynamically.
The problem is the tag 'a' has link X/home.aspx. When i click first time this works since it is available. second time 404 page not found error arising. The link become X/X/home.aspx. Obviously this structure is not available. So, how to redirect.
Thanks
I don't know exactly how your href is continually being added to in this specific scenario (it's a bit of a pitfall in a number of areas, sometimes when using custom controls, etc.), however, you should qualify all of your links from the root by using a prefixed forward-slash (/, i.e. /x/home.aspx).
But we're not done, ASP.NET can transform these too, in other scenarios, so you might want to use the tilde+forward-slash prefix (~/, i.e. ~/x/home.aspx); this indicates the root of the virtual directory where the site is housed.
In this way, regardless of which level of the sites directories you are in, the links always refer to a full path, so to speak.
Your hrefs are relative from the page not from the root of your site...
So do not use "x/home" but use "/x/home".. or use "~/x/home"
Probably you are appending the directory.
If you click for 3rd time you get X/X/X/home.aspx?
Post your code in order to get more help.
Use Page.ResolveUrl
Page.ResolveUrl("~/x/home.aspx")

How do I use Google Analytics with Sitecore 6?

I know that I need to add the tracking code snippet at the bottom of all my pages, but is there a central location to do this?
Or do I need to add this tracking code to all of my templates?
I guess that I could wrap the snippet in a user control, or external .js file, and reference it on each page, but is there a global footer somewhere? The site I'm working on has about 30-40 layouts, and adding it to each one would be a pain!
Thanks in advance!
Actually, the role of a Sitecore layout is exactly this; to act as a global file that all individual page templates "derive" from.
Normally you'd stick the analytics code into the master layout, and use Sitecore sublayout/placeholder techniques to construct the various page templates you need. You would not normally need more than perhaps one or two layouts for any device you are serving content to. And I guess for most sites, the only device in use is regular web content delivery.
That being said, what you could do, is have all the layouts inherit their codebase from a common base class (inheriting from Page), and inject the google code centrally from here. Would still require you to go through all layout files however.
I have not tried the module, I think that is codebehind version. I have made this in XSLT, its pretty fast and easy to make. I have footer.xslt where I put the code that simply checks if page you are standing on uses template that I want to index and does not belong to page names that I want to exclude. Then I have an item with a custom template for Google Analytics with following memo fields.
IncludeTemplates -field contains list of templates that I want to include for analytics :
ExcludeItemsNames -field for excluding pages by item name
contains($includeTemplates, concat('|',./#template,'|')) and not(contains($excludeItemNames, concat('|',./#template,'|')))
Remember #key and #template is always in small letters
If you run many domains don't forget to add pageTracker._setDomainName("www.example.com"); in analytics script so you can separate sub-domains etc. if they use same footer.xslt
Normally we consider the actual Google code as content. Within Sitecore we normally have a settings folder, something like /sitecore/content/settings. This exists outside the root of the site. Beneath this have a settings item with a plain multi-line text field, I think the field type is memo or something similar.
Afterwards create an XSLT that renders out the content of this settings item. Something like (assuming the field is called value in the setting item):
<xsl:value-of select="sc:fld('Value','/sitecore/content/settings/footerJavaScript')" />
You may or may not need to set the disable-output-escaping attribute.
Then on the aspx page that your pages use as the template add a control that looks at the xslt rendering:
<sc:XslFile runat="server" Path="/xsl/footerJavaScript" />
The reason that we normally keep the javascript as content is this allows the client to change the analytics code without having to contact us.

Resources