Generating Outbound Links To Main Website From Widget - asp.net-mvc

I've got an ASP.NET MVC 3 web application that lives on server 1:
http://www.mysite.com
And i've got a widget (also ASP.NET MVC 3 web application) that lives on server 2:
http://widget.www.mysite.com
Now, i want to generate a link to the main website from my widget.
So if i do something like this in the widget project:
#Html.RouteLink("Outbound link", "MainWebsiteRoute", "http", "http://www.mysite.com", string.Empty, null)
It will error (or generate the wrong link) because the route tables are different between the widget and website project.
Even if i copy the route from the main website into the widget one, the controllers/actions don't exist in the widget project, so it won't work.
How do i do it? Do i have to hardcode the URL's?

Ended up duping the routes from the main website that i need in the widget.
Example route in main website:
context.MapRoute(
"Q&A - Individual Q",
"{locationUniqueUri}/questions/{questionUniqueUri}",
new { controller = "Questions", action = "Detail" },
);
Duped route in widget:
RouteTable.Routes.MapRoute(
"Outbound - Q&A - Individual Q",
"{locationUniqueUri}/questions/{questionUniqueUri}"
);
Notice how there are no route defaults - that's because i don't care, since that's concerning matching the route to a controller/action. But this happens in the website, not the widget. All i'm concerned about is generating the URL.
I then created a simple wrapper for RouteLink called OutboundRouteLink which specifies the hostname (for the main website), and generates the link.
I don't think it's too bad a solution. Obviously, it's hard-coded in a way - if the routes change in the main website then i'll have to change the widget routes. But that fine, because if one of my URL's changed, i'd have to do 301's anyway, so the old URL's would still work for the widget (they would get 301'd).
Also, i could go one step further and store the route url in a config file and share that between the projects, which would give me a bit more safety. But there's only around 3 outbound URL's so this should be fine.
Not saying this is the best way to handle it, but im happy with it.

Are you using areas? If not, then perhaps you should be. That way you could simply supply the area for the route and it would be able to resolve the url for you. Given your sample URLs you could build your main site with your widget site as an area. Supplying a empty string for the area parameter in the route values would allow you to reference a controller/action in the main site from the widget site.

Related

Is there a simple way to map a single URL to another URL in ASP.NET MVC?

I have a working ASP.NET MVC application to which I would like to add a very simple URL which I would like to be redirected to another URL, without the Controller part of the path in it.
I.e. I want to be able to tell people to go to mySite.org/Hello and have it direct them to mySite.org/Whatever/WhateverElse?myfun=9, or whatever.
So I added a method in PublicController that redirects Hello to whatever, which works, except it requires me to tell people to go to mySite.org/PUBLIC/Hello, and we'd like to not have the extra word "public" in there.
Hours of confusing study later, I see that I could perhaps add a line in Global.asax.cs such as: routes.MapRoute(name: "Hello", url: "Public/Whatever"); ... or something... but that actually changes the way everything gets routed, and after trying various syntactical variations, nothing has seemed to just change one basic address to map to another basic address.
Is there a simple way to get mySite.org/Hello to map to another URL, without the virtual subdirectory for the public controller?
Create a custom route (it would need to be the first route in the table)
routes.MapRoute(
name: "Hello",
url: "Hello",
defaults: new { controller = "Whatever", action = "WhateverElse" }
);
then /Hello will redirect to /Whatever/WhateverElse

Issue with prerender.io always rendering the default angular route for a list of client side routes

Just want to say I really like prerender.io, but I am currently having an issue with it and I am wondering if maybe I am doing something wrong and people with more experience with the service can help me out.
I am having the same issue with the prerender.io site and also with a Debian Linux box I setup with prerender for local execution.
My new site is a hybrid of ASP.Net MVC and angular, where angular represents workflows (or categories of content) within MVC routes on the server.
An example of a category of content is this:
http://[somesitename]/PublicContent/#!/news
http://[somesitename]/PublicContent/#!/welcome
The MVC server side route is:
http://[somesitename]/PublicContent
and #!/news and #!/welcome are the angular app routes and welcome is also the default route.
When I send my URL to the prerender.io service or my local instance:
http://service.prerender.io/http://[somesitename]/PublicContent/#!/news
The prerender service is only ever rendering:
http://[somesitename]/PublicContent
and is ignoring the client side route after the #!
so for all my pages for each MVC route I am merely getting the default route rendered multiple times...
Is this a bug with prerender.io? Or do I not have something not properly configurered?
I do have the:
<meta name="fragment" content="!">
in the head for all my pages if that would matter.
Talked with the guys over at prerender.io, and it appears that a modification I made to the Asp.Net MVC middleware where it was removing ?_escpaed_fragment_=/ completely was an incorrect modification to this code, which itself was incorrect (the base code removed ?_escpaed_fragment_=/ and replaced it with nothing, I modified the code to remove ?_escpaed_fragment_=/ and replace it with #!).
The prerender.io service expected ?_escpaed_fragment_=/ to exist in the URL and if it finds it it will replace it with #! before calling your website to cache the page. It doesn't expect to find the #!, so it won't properly process the URL if it is there.
So if you are using the Asp.Net MVC middleware you should comment out the following code from PrerenderModule.cs:
// Remove the _escaped_fragment_ from the URL if it exists!
var escapedFull = "?" + _Escaped_Fragment + "=/";
if (url.Contains(escapedFull))
{
url = url.Replace(escapedFull, string.Empty);
}

Special area route (ASP.NET MVC)

I have a unusual problem with ASP.NET MVC3 Routing. I created a area named "Account" and inside that a controller "Main" with action "Login". Now I wanted to create a route, that would look something like this: "/Login" (that means no "/Account/Main/Login"), but I keep failing to do that (I have used the AccountAreaRegistration to register routes, but #Html.ActionLink always skips them and chooses the default area route ("/Account/{controller}/{action}", thus the URL is different from what I want). How can I proceed and solve this issue?
I have solved my issue, it was actually quite stupid. The order of the routes was OK, but the problem was caused by the fact I did use area = "Account" default value in the list of MapRoute's default values. After I deleted it, everything works like a charm.

Using MVC Routes as Shortcodes

We have been trying to implement shortcodes on an ASP.NET MVC web app that allow users to uniquely invoke a given article/page using an assigned short code.
For e.g.: www.mysite.com/power would map to an actual URL: www.mysite.com/Power/Home/.
I have created various routes throughout the site that map these shortcodes to various actions and controllers within the application. From a shortcode/route point of view, everything is working great.
I, however, noticed a couple of interesting things. I have hyperlinks that I use Url.Action method to generate the URL pointing pages. Many of these pages also have short codes associated with them. For e.g.: I have a link that says:
Go to Power page
This is a page that also has the previously mentioned short-code assigned to it. When I use Url.Action, I ideally expect it to create a link as /Power/Home/Index or /Power/Home, but since I also have a route constraint mapped to it, it now generates the link as /power.
Is there a way I can just use the actual link URL when generating links? I only want short-codes when I am sending out emails etc. I want the site to generate actual URLs.
This may or may not be possible, but I wanted to see if there were any ideas out there that I could use.
Anup
Index and Home are likely defined in your route table as defaults for the Action and Controller element. When you generate the Url it wont include the defaults if they aren't needed.
You could write your own Action overload or helper, which would allow you to take more direct control of the generated URL or action link. You could approach it from two different ways: 1) a helper to generate short-code specific urls and links, and/or 2) a helper to generate the full url and/or link. If Url.Action is returning the short-code version due to your routing configuration, I'd think a good place to start would be the second option, creating a helper/extension method that will generate the full url for you.
Here's how I solved this:
Instead of naming a route with short code to point to the action url, I made the route point to a different Controller action which would then redirect to the actual route that I want it to.
For e.g.: Originally I had the code "power" defined in the route table such that it would point to www.mysite.com/Power/Home.
Now instead of pointing it to that action - Index, controller - Home, area - Power, I make it resolve to: action - Power, Controller - Home, Area - ShortCode.
In the controller now, I simply do a RedirectToAction("Index", "Home", new { Area = "Power" });
This ensures that the actual links to /Power/Home do not resolve to the shortcode "power".
This is a simple fix increased the work by a little bit, but works like a charm.

Strange route problem in ASP.NET MVC - default route not hit

I have this two routes currently in my application after decommenting out many other ones. Let me first explain that I have quite a big application already but have come to a problem where my application does not start at the root url anymore.
If I set starting page to default.aspx then webapp starts at (example) http://localhost:55421/Default.aspx. I don't want that. I want it without Default.aspx
So I went into app properties and removed Default.aspx as starting page - now it is blank field (just like in a sample new MVC app if you create it in VS 2008).
But now application does start at the required URL but issues an error:
"The incoming request does not match any route."
Also If I use route debugger it also misses all routes and catches it by catchall route.
I don't know how all of this is possible since as I said above I have two default routes configured at this time:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Pages", action = "Display", slug = "Default" }
);
Any help appreciated
Am I right in thinking you are trying to hit
http://server/{controller}/{action}/{id}
with
http://server/
If you are I think you need to provide a default for the last parameter {id}. You have a default for a parameter slug but without a default for {id} I don't think ASP.NET Routing can hit it.
If I'm right
http://server/Pages/Display
should also not hit the default route, because you are expecting id in Display?
HTH
Alex

Resources