T4MVC adding current page controller to action link - asp.net-mvc

I have the following ActionLink that sits in the home page on the register controller (Index.cshtml)
#Html.ActionLink("terms of service", Url.Action(MVC.Home.Terms()),
null, new { target="_blank" })
Generating the following URL. Why is "register" being added to it? It's as if the link within the Register page which has it's own controller is preappending the register controller to any link in that view?
http://localhost/register/terms-of-service
routes.MapRoute(
"Terms",
"terms-of-service",
new { controller = "Home", action = "Terms" }
);
public partial class HomeController : SiteController
{
public virtual ActionResult Terms()
{
return View(new SiteViewModel());
}

Can you try generating the same link using standard MVC instead of T4MVC, to check whether the behavior is T4MVC specific? MVC behavior with routing can often be puzzling, so it's always good to isolate this first before investigating it as T4MVC thing.

This worked for me... Downloading from a .cshtml file without a redirect, etc... Took a while to get the something that worked
<a href="#Url.Action("ExportAsCSV", "Download", new { target = "_blank" })" >Download2</a>

Related

MVC ActionLink Odd Routing Behavior -- Adds link to the end of the url after hash

I'm working on an MVC .Net 4.5 web app and my links are misbehaving.
Here's my starting URL: http://localhost:58982/Game/Index
Here's the RAZR code and resulting html:
#Html.ActionLink("Occasion", "Index", "Occasion")
Occasion
But when I click the link my URL looks like this: http://localhost:58982/Game/Index#/Occasion
When a link takes me to the same page the browser does not refresh and the controller is not called.
Is there a setting I need to change somewhere?
if your action takes no parameter you don't need to pass parameter:
#Html.ActionLink("Occasion", "Index", "Occasion")
but if your action takes parameter:
public ActionResult Index(int ID)
{
//
}
it would be something like this:
#Html.ActionLink("Occasion", "Index", "Occasion", new {Id=Model.Id},null)

asp.net mvc4 signout link route not found

Using asp.net mvc4. I can't hit ~/Account/LogOff from my app. The default route should catch it and route it to the appropriate controller. in routeconfig.cs
routes.MapRoute(
name: "Home",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Shouldn't that catch the url?
Code for the link creation
#Html.ActionLink("Signout", "LogOff", "Account" , new{controller = "Account"
, action = "LogOff"}, new{ target = "_self"})
For some reason that is driving me crazy, I can't hit
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
var fam = FederatedAuthentication.WSFederationAuthenticationModule;
fam.SignOut(false);
SignOutRequestMessage signOutRequest = new SignOutRequestMessage(new Uri(fam.Issuer), fam.Realm);
return new RedirectResult(signOutRequest.WriteQueryString());
}
I've tried adding a route before and after the "Home" maproute. Neither one seems to work. What in the world am I missing here? I've written dozens of asp.net mvc apps and have not had this problem. It's blowing my mind. Please help.
Cheers,
~ck
The reason is because you have a [HttpPost]. What it basically means is that it fetches request coming from a submit button from forms but since your not using a submit button neither a form, your Logoff action will be skipped.
You can resolve this by 2 reasons:
1.) Change the [HttpPost] to [HttpGet]
2.) Just simply direct your link to your action:
#Html.ActionLink("Signout", "LogOff", "Account")
Oh I was doing a get via the link click. The method is for post. I wrapped the link in a form tag and on the link click I submit the form as usual. This fixed the problem and im able to hit my controller method.
You need to remove [HttpPost] attribute from the LogOff() action. #Html.ActionLink() will create a regular link (<a> tag), so clicking on it will issue a GET request.

Generating Route Url to MVC controller action from WebAPI

I'm used to generating route URLs to other controller actions within an MVC controller action using something similar to below:
public class ApplicationController : Controller
{
public ActionResult Index( )
{
var url = Url.RouteUrl("routename",
new { controller = "Application", Action = "Index2" , other="other" });
}
public ActionResult Index2( string other)
{
}
}
But I also need to be able to generate URLs to MVC controller actions from within webapi too, How would I go about doing this?
There seems to be a UrlHelper property on the APIController but I cant find any examples of how to use this and have not been able to figure it out myself.
UPDATE :
The reason I am trying to generate a url is that this particular webapi method sends an email which provides the recipient with a link to direct the user back to an appropriate section of the site. I obviously want to get away from hardcoding this as it will not work for different deployments and also if I begin changing the routing this link will be broken. Is there a better approach to doing this?
You can use MVC route names as well with web API UrlHelper. Example,
Url.Link("Default", new { Controller = "Account", Action = "Login" });
or
Url.Route("Default", new { Controller = "Account", Action = "Login" });

What is wrong with my area routing in my bin deployed MVC4 app?

I have just deployed an MVC4 .NET 4.0 app to my web host, for 'live' deployed testing. Non -area routes are working fine, e.g. my
#Html.ActionLink("Register as a Client", "Register", "Account", new { registrationType = "Client"}, null)
link works fine, and the link opens the correct page. However, with a link to an area based action like this:
#Html.ActionLink("Authors", "Index", "Home", new { Area = "Author", registrationType = "Author" }, null)
the link actually rendered to the browser is missing action and controller, i.e.
http://mylivedomain.com/?Area=Author&registrationType=Author
It may be worth noting that the css bundling feature of MVC4 was not working after deployment, and I rolled back to using classic style links to individual stylesheets.
MAYBE RELATED: My question: Why is unmodified template code in my MVC4 app trying to register areas twice?
JUST IN: Removing the default action from the area route mappings for the default rouite solved this problem. There was no default controller to start with, in the VS2012 template code.
Try checking this.ControllerContext.RouteData.DataTokens["area"] in your area's action methods.
I've had a situation with similar issue in which the area name was simply an empty string.
Setting the DataToken in the action method might provide you a quick fix but it doesn't answer the question why MVC doesn't set the area name.
In your case because you specify area in query string, the routes from Global.asax.cs should apply. I belive you have something like this there:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
).DataTokens.Add("area","Author");
}
This code makes Home/Index default route and skips Home/Index in url. If you change controller = "Home" on something else for example controller = "Home2" you will have displayed full link for Home/Index and new default route Home2/Index. Similar apply to default routes in areas if you have them specified.
In your global.asax.cs make sure you have this line in your Application_Start:
AreaRegistration.RegisterAllAreas();
In each area, you should have AreaRegistration.cs something like this:
public class testAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "test";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"test_default",
"test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
With the #Html.ActionLink
use this format
#Html.ActionLink("Authors", "Index", "Home", new { Area = "Author", registrationType = "Author" }, new{})
Solved my issue.
Do you happen to inherit PortableAreaRegistration from MvcContrib in any of your areas?
We used to have exactly the same symptoms (works locally, not on server) until we removed all the PortableAreaRegistrations from Portable Areas and reverted to using simply AreaRegistration since MVC4 can register a portable area without any additional libraries.

How do I do Short URLs in MVC?

Suppose I want to publish (like in paper catalogs) some "short URLs" that are easy to type/remember, but I want them to redirect to a verbose, SEO-friendly URL. How do I accomplish that with MVC routes?
Example:
http://mysite.com/disney
becomes
http://mysite.com/travel/planning-your-disney-vacation (with "travel" as the Controller)
The things I've tried:
Just setup a route for it. Problem: the URL doesn't change in the browser (it stays "/disney".
Use NuGet package RouteMagic (see Haacked's article). Problem: I get an error: The RouteData must contain an item named 'controller' with a non-empty string value. I think this is because I don't have a static word before my controller ("travel") like he did (with "foo" and "bar")???
Use a redirect module (like Ian Mercer's). Problem: the route matches on my HTML.ActionLinks when creating URLs which I don't want (Haacked mentions this in his article and says that's why he has GetVirtualPath return NULL ...?)
I'm out of ideas, so any would be appreciated!
Thanks!
You could set up a catch-all type route, to direct all /something requests to a specific action and controller, something like:
routes.MapRoute(
"ShortUrls",
"{name}",
new {controller = "ShortUrl", action = "Index", name = UrlParameter.Optional}
);
(depending on how the rest of your routing is set up, you probably don't want to do it exactly like this as it will likely cause you some serious routing headaches - but this works here for the sake of simplicity)
Then just have your action redirect to the desired URL, based on the specified value:
public class ShortUrlController : Controller
{
//
// GET: /ShortUrl/
public ActionResult Index(string name)
{
var urls = new Dictionary<string, string>();
urls.Add("disney", "http://mysite.com/travel/planning-your-disney-vacation");
urls.Add("scuba", "http://mysite.com/travel/planning-your-scuba-vacation");
return Redirect(urls[name]);
}
}
I just faced the same problem.
In my Global:
routes.MapRoute(
"ShortUrls",
"{name}",
new { controller = "Home", action = "Index", name = UrlParameter.Optional }
);
In my Home Controller:
public ActionResult Index(string name)
{
return View(name);
}
This way is dynamic, didn't want to have to recompile every time I needed to add a new page.
To shorten a URL you should use URL rewriting technique.
Some tutorials on subject:
url-rewriting-with-urlrewriternet
url-routing-with-asp-net-4
URL rewriting in .Net

Resources