ASP.NET Routing optional first parameter - asp.net

I am new ASP.NET Routing and have a question.
On the site I am developing, visitors sign up and create an account (with a display name), such as JohnDoe and the site personalises itself, with information pertaining to the display name.
For example (in order of the routing table, I currently have):
http://www.domain.com/ - Generic index page
http://www.domain.com/Page1 - Generic page1
http://www.domain.com/Page2 - Generic page2
http://www.domain.com/JohnDoe - Personalised index page
http://www.domain.com/JohnDoe/Page1 - Personalised page1
http://www.domain.com/JohnDoe/Page2 - Personalised page2
The above is working fine (I simply have a rule for every eventuality).
My problem is that, I now need to create asp:HyperLink controls on the pages of the site. Currently, I am using this:
NavigateUrl="<%$ RouteUrl:RouteName=ROUTENAME %>"
....in the tag of the HyperLink control
How can I, given the following addresses....
http://www.domain.com/Example - Generic example page
http://www.domain.com/JohnDoe/Example - Personalised example page
....match ROUTENAME, where the first parameter can be optional?
I could obviously create two routes, as follows....
Routes.MapPageRoute("Example_No_Displayname", "Example", "~/Example.aspx")
Routes.MapPageRoute("Example_With_Displayname", "{Code}/Example", "~/Example.aspx")
....but that means that the route names need to be different and I need to bind the Hyperlink control to match both of them.
I hope I have made myself clear and I appreciate any assistance the community may be able to give.

It would be somewhat atypical to put the username itself in the URL. The actual user identity/name would typically be extracted from some established security context/token, such as a cookie, so you could use the same URLs for both the anonymous pages and the personalized pages. Is there a specific reason you want to have the username in the URL?

You shouldn't need to match directly on the route name if you use the GetRouteUrl method. That way you can still use the two routes you need to make this work. See the full sample here.

Related

In Sitecore, how to change or set PageMode

In Sitecore, I have users who are using the editing ribbon to add content to pages. However, there are some pages that I want to prevent EditMode completely from that user's role. This is based off of a branch template, so I can't just revoke privileges for each page. I need some way to set the Sitecore.Context.PageMode to be Normal.
Is there an API for setting the PageMode?
While I was unable to find a C# API, I did find that I could just use a URL Redirect that looks something like this:
if (!Sitecore.Context.PageMode.IsNormal && !IsAdministrator())
{
String id = Sitecore.Context.Item.ID.ToString();
Response.Redirect("/?sc_mode=normal&sc_itemid=" + id + "&sc_lang=en");
}
This will set the PageMode to Normal if it in any other state.
your redirect method should work, but it also turns off the PageEditor mode for other pages the editor visits after the redirect.
You could also check if the Page is in EditMode and the user is part of a certain Role and for that (sub)layout show standard .NET controls instead of the Sitecore sc-controls.
Like <asp:Literal /> instead of <sc:Text />
I would suggest that rather than redirecting the user/hard-coding this to specific pages you make create a rule and make use of the Rules Engine. This will allow you to reuse the code and turn on-/off much easier through the content editor.
There is already a condition to select the role:
/sitecore/system/Settings/Rules/Common/Conditions/Security/User Role
So you will just need to create an action to switch to Normal mode. In your action, you can call the following code:
Context.Site.SetDisplayMode(Sitecore.Sites.DisplayMode.Normal, Sitecore.Sites.DisplayModeDuration.ResetAfterRequest);
Wrap it in a check like wilsjd has suggested.
Some info on the Rules Engine if you are not familiar with it:
Decoupling through the Rules Engine
All About the Sitecore ASP.NET CMS Rules Engine

How does Asp.net Knows which Page to Generate?

When a client is on page A.aspx , and he press some button there is a postback.
The server knows which page to rebuild according to the request.
but how does the client knows which page to re-ask ? by the current url of his browser ?
where this information is saved in the client side ?
Its defined in the action property of <form>. The client does not need to re-ask, the server sends a response of his request.
ASP.NET is just a part of the .NET framework, but what every client sees on a web browser in plain old HTML.
ASP.NET gives you several controls that makes it easy to use them programatically, so we can set all sort of things in our code (that is run before the page is showing) to do the exactly what we want.
every link, button, image, grid, it's just HTML tags, like <a> for links, <input type="button"> for buttons etc...
Keep in mind that now, there are 2 variantes of the ASP.NET, the WebForms and the MVC (you can also read about choosing one in prole of the other)
in every ASP.NET WebForms there is always a <form> on the start of the <body> and wrapps all your code, so, any submit will do a PostBack into the same file name, in your example A.apsx will always post into A.aspx, then if you want, for example, send that request to B.aspx you need to have a Click Event that would use the Server.Transfer("B.aspx") and that would redirect the entire post to B.aspx just like it was a post from B.aspx
in the newest pattern, the ASP.NET MVC, it drives with Routes witch let's you set up any, every, one, multiple, ways to reach the same page. In MVC the URL does not point to a specific page, but to a specific Controller and it's up to the Controller to send, after processing the data, to a specific View, that is why in MVC there are no pages in the url (though you can add it to the route if you want, and you can accomplish the same with WebForms using a Routing plugin).
Now, in MVC it's there is no <form> wrapping up your entire code, you need to, if you want to submit something, create your own <form> and point to the correct route
but, just like in Webforms or any HTML page, posts are made through form submittion, and it's "path" it's always whats in the form attribute action that let's you know what's the next step.
I hope this helps you realizing that there is no big monster in ASP.NET, that is only a way to reuse controls and access them programmatically and that, in the end, it's all HTML :)
A general answer: on the client side it's either a submit from within a form or a link.
The form points to either a relative URL (that means the current URL plays a key role) or an absolute URL (the current URL plays little to no role).
For links it's generally the same: either they are relative or absolute. One big difference: links are use HTTP GET while forms can use HTTP POST (thus transferring more data without encoding them to the URL as parameters).
For a button it's the form that gets submitted.

ASP.NET MVC3 URL and hiding Id's

I have a heap of entities that are keyed by ID. In one screen I load a "Subject" based on the ID like so: "/Results/Subject/53" On that same screen I have a combo box that maintains a list of all subjects. The user can change the selection in this combo to another subject and I load the results for that subject using ajax. When I do this the URL in the browser is stale as I might be now be looking at /Results/Subject/45 If a user reloads I reload the original document and not the new one.
I would either like to update the URL (which sounds hacky as) or I would like to base my navigation on something else besides the Id as part of the URL. How can I do this? How can I load controllers for specific items without specifying the Id as part of the URL.
You can also pass the id via the HTTP GET parameter: /Results/Subject?id=45 or HTTP POST parameter.
However, I doubt that this will answer your question.
A colleague of mine has encountered the similar problem, and he solved it by altering the browser URL string (by attaching a specific #anchor to it).
Easiest way would be to ditch the ajax when that drop-down changes, and just navigate to a new url (/Results/Subject/NewID).
If you want to keep the ajax, you could just put the key at the end of the url with a # like "/Results/Subject#53", then load it via Ajax (the #53 will not be passed over to the server). That way, when the user changes the drop-down, you can navigate to "/Results/Subject#NewID" without it reloading the page.

Convert HTML Forms to ASP.NET forms with a silent post and response handler

I want to write a DotNetNuke module that can take an HTML form and parse or transform it into an asp.net form that would then do a HTTPPost to the page specified in the HTML Form's action property.
We regularly run into the need to use pre-existing forms (from existing sites and Service Providers like Paypal and Constant Contact). Currently, we either use an IFrame, manually convert the form into an ASP.NET user control, or use a forms module to recreate the form. It seems like it should be fairly easy to create an automated way to handle these with ASP.NET.
My quick plan:
1.) Admin Users will paste the form into a settings page and then click a convert button
2.) The code will parse the HTML and generate a ascx User Control from it and store the posting address. We may just have to add runat="server" into each of the form controls
3.) The admin user will be able to specify a variety of response codes and corresponding messages. (i.e. 1 -> "Thank you for your Donation", 2-> "We were not able to process your request at this time due to ...")
Users would then fill out the form and hit submit. The system would get the names and values of all form controls and Silent Post that to the posting address and get the response code and then display the corresponding message.
Any thoughts or suggestions of the best way to do this? Are there any tools that already do this or would be helpful?
Thanks,
David O'Leary

MVC: capture route url's and pass them to javascript function

Short:Is there a way to have a route-definition that will pass the "CONTROLLER/ACTION" string value to a JavaScript function in stead of actually going straight for the controller action?
More:I have a masterpage which contains the navigation of the site. Now, all the pages need this navigation wrapped around it at all times, but because I didn't want the navigation to constantly load with each pagecall, I changed all my pages to partialviews.
These partial views are loaded via the JQuery.Load() method whenever a menu item is clicked in the navigation.
This all worked very good, up till now because I noticed it's also a requirement of the website to be able to link directly to page X, rather then default.aspx.
So, as an example:The main page is my "default.aspx" page, this utilizes my master page with the navigation around it. And each call to a new page uses a javascript function that loads that particular partial view inside a div that is known in my masterpage. So, the url never changes away from "default.aspx", but my content changes seemlesly.
The problem is, those url's also need to be available when typed directly into the address bar. But, they're partial views, so loading them directly from the address bar makes them display without any masterpages around them. Therefore my question if it might be possible to capture the route typed into the address bar and pass that on to my JavaScript function that will load that route in the content div.
(I hope I explained it ok enough, if not, feel free to ask more information)
You are 100% correct to not want to hard code your URLs in your javascript code as it demolishes one of the primary tenants of MVC to do so. I'm one of those "separation of concerns" guys who will not write a single line of javascript outside of a dedicated .js file so I cannot dynamically specify the URL the way tuanvt has. What I do is use MVCs Url.Action method to emit my service URLs into hidden inputs on the master page (or the specific page if it is not used in multiple places). Then my script file simply pulls the value out of that hidden input and uses it just fine.
ASP.NET MVC View Source
<input id="serviceUrl" type="hidden" value="<%= Url.Action("Action", "Controller") %>" />
JS Source
$.getJSON($("#serviceUrl").val(), function(data) {
//write your JS success code here to parse the data
});
First challenge, as you are using AJAX to load the partial pages you need client accessible URLs for the javascript to call. Second challenge, you need URLs that will load the HomeController and pass the 'page' portion of the URL into the javascript.
For the first aspect I'd create some abstracted routes, i.e. "/ajaxaccess/{controller}/{action}/{id}" for the partial pages. That would be the first registered route. A second route would accept any controller/action reference and always get processed by the HomeController Index action.
In the /Home/Index action you grab the requested URL and slice it up, take the /{controller}/{action}/... section and pass that into your default.aspx using TempData. In your page check for the existence of the TempData and if it exists use the value therein to trigger your AJAX page load for the partial page (don't forget that you'll need to prepend '/ajaxaccess' (or whatever you choose) to the URL before it's passed to your page.
I'm not going to provide code here as I think the information you'll gain from working through this yourself will be invaluable to you moving forward.
You could use hash anchor (#) on your url and read it with javascript.
var url = document.location.toString();
if (url.match('#')) {
anchor = url.split('#');
// do whatever with anchor[1] ..
}
You can do something like this, put this in your javascript code on the view:
var szUrl=<%= ViewContext.RouteData.Route.ToString()%>;
Then the current route will be stored on the variable szUrl.

Resources