How to get actual URL from a list of routes? - c#

i have a set of routes defined in System.Web.Routing and in need to get the actual url's with the .aspx extension. i've tried this code but i'm doing something wrong here:
var path = RouteTable.Routes.GetVirtualPath(null, item.Link, null);
var link = path.Route.GetVirtualPath(null, null);
if (link.VirtualPath.ToLower().Contains("~/displaycmspage.aspx?pagename="))
{
//do work on url here
}
any idea on how i can do this? The item.link is a custom object where i have the route.

ok, so i found the answer :
var path = RouteTable.Routes[item.Link];
Route ruta = path as Route;
var link = ruta.RouteHandler as PageRouteHandler;
if (link.VirtualPath.ToString().ToLower().Contains("~/displaycmspage.aspx?pagename="))
{
//do work on url here
}

Related

AbsolutePath with QueryString

I have the following code:
if (Request.Url.AbsolutePath == "/Guidance.aspx")
{
if (Request.IsSecureConnection)
{
Reponse.Redirect("http://www.example.com/Guidance.aspx");
}
return;
}
The thing is that Guidance can have a querystring with it. I like to then Redirect to the same page name and append the querystring. Haven't found a way to do this.
if (Request.Url.AbsolutePath == "/Guidance.aspx?id='vid09'")
{
if (Request.IsSecureConnection)
{
Reponse.Redirect("http://www.example.com/Guidance.aspx?id='vid09'");
}
return;
}
How can I simplify the code above to do it with any querystring that comes its way.
Use UriBuilder and replace parts you need. Something like:
var builder = new UriBuilder(Request.Url);
builder.Scheme = "http";
Reponse.Redirect(builder.ToString);
string myUrl = Request.RawUrl.toString();
if (myUrl.Contains("/Guidance.aspx")
{
if (Request.IsSecureConnection)
{
var queryString = myUrl.Substring(myUrl.IndexOf("?"));
Reponse.Redirect("http://www.example.com/Guidance.aspx" + queryString);
}
return;
}
Don't get fancy, the URI is already parsed for you (don't do it yourself with unreliable regular expressions). The Url property you're using is a System.Uri object. You may simply compare the scheme, host, and any HTTP segment you may need, then construct your redirection URI by adding only the query string component from the original URI. All you need is in the Uri class.

Adding controller/action to URI using UriBuilder

I am trying to create a Url after a certain operation and this url should point to a different controller and actions. I also need to include some parameters so they provide the target controller with information needed. so lets say I have a controller called:
DoWorkController.cs
and an Action
public void Add(params...){..}
I am using UriBuilder in my homepage controller like this:
UriBuilder builder = new UriBuilder();
builder.Host = System.Web.HttpContext.Current.Request.Url.Host;
builder.Port = System.Web.HttpContext.Current.Request.Url.Port;
//got stuck here
Uri ret = builder.Uri;
return ret;
I want it to pull the controller name and action name and assign it to builder then add parameters, I am not sure how to do this. Suggestions??
EDIT
I solved the path-to-controller-to-action problem, I am still stuck on adding parameters to the url.
UriBuilder builder = new UriBuilder();
builder.Host = System.Web.HttpContext.Current.Request.Url.Host;
builder.Port = System.Web.HttpContext.Current.Request.Url.Port;
string path;
if (operation == 1)
path = Url.Action("Add", "DoWork");
else if(operation ==2)
path = Url.Action("Delete", "DoWork");
else
throw new ArgumentException("Operation is neither Add or Delete");
if (path != null)
{
builder.Path = path;
}
Uri ret = builder.Uri;
You can add parameters to your Url.Action in following way:
Url.Action("GetByList", "Listing", new { name = "John"})
If you are on the home page controller, then you already know the controller name, no?
But to answer your question, the way to get the controller and action name is to get it from the routeData:
RouteData rd = ViewContext.RouteData;
var controllerName = rd.GetRequiredString("controller");
var actionName = rd.GetRequiredString("action");

Get site url on mvc

I want to write a little helper function that returns the site url.
Coming from PHP and Codeigniter, I'm very upset that I can't get it to work the way I want.
Here's what I'm trying:
#{
var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
var baseurl = urlHelper.Content("~");
}
<script>
function base_url(url) {
url = url || "";
return '#baseurl' + url;
}
</script>
I want to return the base url of my application, so I can make ajax calls without worrying about paths. Here's how I intend to use it:
// Development
base_url(); // http://localhost:50024
// Production
base_url("Custom/Path"); // http://site.com/Custom/Path
How can I do something like that?
EDIT
I want absolute paths because I have abstracted js objects that makes my ajax calls.
So suppose I have:
function MyController() {
// ... js code
return $resource('../MyController/:id');
}
// then
var my_ctrl = MyController();
my_ctrl.id = 1;
my_ctrl.get(); // GET: ../MyController/1
This works when my route is http://localhost:8080/MyController/Edit but will fail when is http://localhost:8080/MyController .
I managed to do it like this:
#{
var url = Request.Url;
var baseurl = url.GetLeftPart(UriPartial.Authority);
}
Thank you all!
Are you aware of #Url.Action("actionname") and #Url.RouteUrl("routename") ?
Both of these should do what you're describing.
Instead of manually creating your URL's, you can use #Url.Action() to construct your URLs.
<p>#Url.Action("Index", "Home")</p>
/Home/Index
<p>#Url.Action("Edit", "Person", new { id = 1 })</p>
/Person/Edit/1
<p>#Url.Action("Search", "Book", new { title = "Gone With The Wind" })</p>
/Book/Search?title="Gone+With+The+Wind"
Now the absolute best reason to go with this option is that #Url.Action automatically applies any vanity URL routes you have defined in your Global.asax file. DRY as the sub-saharan desert! :)
In your case, your can create a 'custom path' in two ways.
Option A)
<p>#Url.Action("Path", "Custom")</p>
/Custom/Path
Option B)
You can create a route using the Global.asax file. So your controller/action combo can be anything you want, and you can create a custom vanity route url - regardless of the controller/action combo.

Calling node.NiceUrl gives me # in Umbraco

Doing a project in Umbraco, and i've encountered problems in one case that when calling node.NiceUrl I get # as the result. What is weird though is that if i debug it somehow it resolves into the correct url.
var pages = Pages.Select((item, index) => new
{
Url = item.NiceUrl,
Selected = item.Id == currentPage.Id,
Index = index
}).ToList();
Where Pages is obtained from:
CurrentPage.Parent.ChildrenAsList
If I do it this way, it works, but I don't know why.
Url = new Node(item.Id).NiceUrl,
I've encountered this error and it was because the id belonged to a media node.
Media is treated differently to other content and there's no easy way of getting the url because different types of media store the url in different ways depending on context. That's why the NiceUrl function doesn't work for media (according to the umbraco developers).
My specific scenario was using images that had been selected using a media picker. I got the url via the following code. I wrapped it up in an extension method so you can consume it from a template in a convenient way.
public static string GetMediaPropertyUrl(this IPublishedContent thisContent, string alias, UmbracoHelper umbracoHelper = null)
{
string url = "";
if (umbracoHelper == null)
umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
var property = thisContent.GetProperty(alias);
string nodeID = property != null ? property.Value.ToString() : "";
if (!string.IsNullOrWhiteSpace(nodeID))
{
//get the media via the umbraco helper
var media = umbracoHelper.TypedMedia(nodeID);
//if we got the media, return the url property
if (media != null)
url = media.Url;
}
return url;
}
Try like this
Url = umbraco.library.NiceUrl(Item.Id);

ASP.NET MVC: Redirect from query string params to a canonical url

In my Asp.Net Mvc project I'd like to have a good looking urls, e.g. mysite.com/Page2, and I want to redirect from my old style urls (such as mysite.com?page=2) with 301 state so that there won't be two urls with identical content. Is there a way to do it?
As far as I know Asp.Net binding framework doesn't make difference between query string and curly brace params
I am not sure, I got your question right. It seems, your current setup relies on those GET parameters (like mysite.com?page=2). If you dont want to change this, you will have to use those parameters further. There would be no problem in doing so, though. Your users do not have to use or see them. In order to publish 'new style URLs' only, you may setup a URL redirect in your web server. That would change new style URLs to old style URLs.
The problem is the 301. If the user requests an old style URL, it would be accepted by the webserver as well. Refusing the request with a 301 error seems hard to achieve for me.
In order to get around this, I guess you will have to change your parameter scheme. You site may still rely on GET parameters - but they get a new name. Lets say, your comments are delivered propery for the following (internal) URL in the old scheme:
/Article/1022/Ms-Sharepoint-Setup-Manual?newpage=2
Note the new parameter name. In your root page (or master page, if you are using those), you may handle the redirect permanent (301) manually. Therefore, incoming 'old style requests' are distinguishable by using old parameter names. This could be used to manually assemble the 301 in the response in ASP code.
Personally, I would sugesst, to give up the 301 idea and just use URL redirection.
Well, as far as I can see performing such redirection in ASP.NET MVC might be tricky. This is how I did it:
global.asax:
routes.Add(new QueryStringRoute());
routes.MapRoute(null, "Article/{id}/{name}",
new { controller = "Article", action = "View", page = 1 },
new { page = #"\d+" }
);
routes.MapRoute(null, "Article/{id}/{name}/Page{page}",
new { controller = "Article", action = "View" },
new { page = #"\d+" }
);
QueryStringRoute.cs:
public class QueryStringRoute : RouteBase
{
private static string[] queryStringUrls = new string[]
{
#"~/Article/\d{1,6}/.*?page=\d{1,3}"
};
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string url = httpContext.Request.AppRelativeCurrentExecutionFilePath;
foreach (string queryStringUrl in queryStringUrls)
{
Regex regex = new Regex(queryStringUrl);
if (regex.IsMatch(url))
{
long id = 0; /* Parse the value from regex match */
int page = 0; /* Parse the value from regex match */
string name = ""; /* Parse the value from regex match */
RouteData rd = new RouteData(this, new MvcRouteHandler());
rd.Values.Add("controller", "QueryStringUrl");
rd.Values.Add("action", "Redirect");
rd.Values.Add("id", id);
rd.Values.Add("page", page);
rd.Values.Add("name", name);
rd.Values.Add("controllerToRedirect", "Article");
rd.Values.Add("actionToRedirect", "View");
return rd;
}
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
QueryStringUrlController.cs:
public class QueryStringUrlController : Controller
{
public RedirectToRouteResult Redirect(long id, int page, string name,
string controllerToRedirect, string actionToRedirect)
{
return RedirectToActionPermanent(actionToRedirect, controllerToRedirect, new { id = id, page = page, name = name });
}
}
Assuming you have such routing as in my global.asax file (listed above) you can create a custom Route class that will handle incoming requests and map them on a special redirection controller which will then redirect them to appropriate urls with 301 state. Then you must add this route to global.asax before your "Article" routes
If you're using IIS 7, the URL Rewrite Module should work for your scenario.

Categories

Resources