asp.net mvc4 signout link route not found - asp.net-mvc

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.

Related

How to hide action and controller from url : asp.net mvc [duplicate]

This question already has answers here:
Routing in ASP.NET MVC, showing username in URL
(2 answers)
Closed 6 years ago.
Introduction
I am working on demo application where users can register.Users table have "username" field.There is "detail" action in "home" controller accepting parameter of string "username".
Code
public ActionResult Detail (string username)
{
return View();
}
Then url will be
www.example.com/home/Detail?username=someparam
Problem
Can i setup route like that ?
www.example.com/someparam
If its possible, then please let me know. Any kind of help or reference will be appreciated.
Thanks for your time.
That is doable if you change the way your routes are defined. Let's assume that you use dot net 4.5.2
Have a look in RouteConfig under App_Start.
A typical route definition is defined like this :
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Nothing stops from changing the route to look like this :
routes.MapRoute(
name: "Default",
url: "{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
We are basically hardcoding the controller and action to be a certain value so now you could just have url/paramname and it will hit the hardcoded combination.
This being said I would not do things like this as it's against the way MVC works
MVC routes are url/controller/action. You can skip the action for generic stuff like an Index for example and your URL becomes url/controller. MVC needs to be able to identify which controller you want to hit and which action and it's best to stay within the conventions it has.
Plus, each application will typically have more than one controller, which allows a nice Separation of Concerns. Now you've hardcoded yourself ito having just one controller and action.
What you are suggesting can be done a lot easier in a webforms manner though so maybe you want to look into that.
If you define code like this
[HttpGet, Route("api/detail/{username:string}")]
public ActionResult Detail (string username)
{
return View();
}
Then url will be
www.example.com/api/Detail/someparam
So I guest you define as following, please try with your own risk!
[HttpGet, Route("/{username:string}")]
Url will be:
www.example.com/someparam

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)

T4MVC adding current page controller to action link

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>

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

asp.net mvc routing: how to use default action but non-default parameter?

I'm rewriting the question, as the answers so far show me that I have not defined it good enough. I'll leave the original question for reference below.
When you set up your routing you can specify defaults for different url/route parts. Let's consider example that VS wizard generates:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults
In this example if controller is not specified, DefaultPageController will be used and if action is not specified "Index" action will be used.
The urls will generally look like: http://mysite/MyController/MyAction.
If there is no action in Url like this: http://mysite/MyController then the index action will be used.
Now let's assume I have two actions in my controller Index and AnotherAction. The urls that correspond to them are http://mysite/MyController and http://mysite/MyController/AnotherAction respectively. My "Index" action accepts a parameter, id. So If I need to pass a parameter to my Index action, I can do this: http://mysite/MyController/Index/123. Note, that unlike in URL http://mysite/MyController, I have to specify the Index action explicitly. What I want to do is to be able to pass http://mysite/MyController/123 instead of http://mysite/MyController/Index/123. I do not need "Index" in this URL I want the mvc engine to recognize, that when I ask for http://mysite/MyController/123, that 123 is not an action (because I have not defined an action with this name), but a parameter to my default action "Index". How do I set up routing to achieve this?
Below is the original wording of the question.
I have a controller with two methods definded like this
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(SomeFormData data)
{
return View();
}
This allows me to process Url like http://website/Page both when the user navigates to this url (GET) and when they subsequently post back the form (POST).
Now, when I process the post back, in some cases I want to redirect the browser to this url:
http://website/Page/123
Where 123 is some integer, and I need a method to process this url in my controller.
How do I set up the routing, so this works? Currently I have "default" routing generated by the wizard like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults
I tried adding another controller method like this:
public ActionResult Index(int id)
{
return View();
}
But this doesn't work as ambiguous action exception is thrown:
The current request for action 'Index'
on controller type 'PageController'
is ambiguous between the following
action methods:
System.Web.Mvc.ActionResult Index() on
type PageController
System.Web.Mvc.ActionResult
Index(Int32) on type PageController
I must add, that I also have other actions in this controller. This would have worked if I didn't.
Here is how this can be resolved:
You can create a route constraint, to indicate to the routing engine, that if you have something in url that looks like a number (123) then this is an action parameter for the default action and if you have something that does not look like a number (AnotherAction) then it's an action.
Consider This code:
routes.MapRoute(
"MyController", "MyController/{productId}",
new {controller="My", action="Index"},
new {productId = #"\d+" });
This route definition will only match numeric values after MyController in http://mysite/MyController/123 so it will not interfere with calling another action on the same controller.
Source: Creating a Route Constraint
If you keep the variable name to remain being ID, you don't need to change anything.
Rename the post one to "PostIndex" and add this attribute:
[ActionName("Index")]
Same question on SO here.
Ok, here's a cut/paste answer for you, if that helps.
public ActionResult Index() {
return View();
}
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]
public ActionResult PostIndex(SomeFormData data) {
return View();
}
Oh i got it now. I think It's not possible with default route, You need to map custom routes.
// /MyController/AnotherAction
routes.MapRoute(
null,
"MyController/AnotherAction",
new { controller = "DefaultPage", action = "AnotherAction" }
);
// /MyController
// /MyController/id
routes.MapRoute(
null,
"MyController/{id}",
new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
);
ps. Default routes like /MyController/id must mapped at last.
I think you want return the same view, but you need understand you are doing two differents things. One is receive post, and another is accessing by get, and another is accessing by get and parameter...
You should do 3 actionresult with different names, and return de same view as View("ThisIsTheResult")

Resources