I have two question about generating routes in MVC 5.
This is example:
routes.MapRoute(
name: "ActionSite",
url: "{userName}/sites/{action}/{localSiteName}",
defaults: new { controller = "Site" }
);
#Url.RouteUrl("ActionSite", new { action="Edit", siteOrder = site.Order, localSiteName = site.LocalName, userName = ViewBag.UserName })
generates the next url:
https://localhost:44344/TestUser/sites/Edit/Site2?siteOrder=1
1)How to hide variables? I want to hide: ?siteOrder=1
2)TestUser is userName. At this moment I set manually it in all [Authorize] actions. Can I do this one time in some special method?
About first question, RouteUrl assumes you are going to use the URL in a GET method and when you are using GET verb you have to append query string to the URL. siteOrder has to be in query because you did not put it into URL template. Any extra parameter goes into query string.
Solution here is to use POST instead of GET. Down side would be losing simple GET calls ( anchor) from client side. You have to use #Html.BeginForm instead of #Html.ActionLink.
Second question is not clear, if you generate URL like https://localhost:44344/TestUser/sites/Edit/Site2?siteOrder=1 then you will get username form URL.
for example:
public ActionResult Edit(string userName, string localSiteName){ }
username here will be "TestUser" and you have to check authentication if userName is same as User.Identity.GetUserName()
Or you can write AuthenticationFilter to do the authentication job for you.
But if you mean a way that Url.RouteUrl automatically fill in userName property based on User.Identity I think answer is no. You have to retrieve username somewhere in ActionFilters or in Action or if you are using ASP.Identity then you already have the user name all the way down to the View, just you need to call
#User.Identity.GetUserName()
in your View or Controller to get it.
Related
I have a site entry controller that is used via a url generated by a single sign on manager. The SSO manager appends an identifying hash as an action parameter to the url of the system it is attempting to sign on to.
So the url being generated by the SSO manager looks like:
http://mysite/Entry/SingleSignOn?action=123456789ABCDEFG
I think I just need to set up a better route, but I haven't been able to get it to work yet. When I try to get the action from the url via standard MVC binding, it is giving me the name of the action, not the hash I need:
public ActionResult SingleSignOn(string action)
{
// action returns "SingleSignOn"
var querystring = Request.Url.Query; //returns "?action=123456789ABCDEFG"
return RedirectToAction("Index");
}
I know I can just split open the querystring, but would prefer not to if possible. It doesn't seem like a terribly complex problem, but I am just not finding the right route.
You can use Request.QueryString["action"] to explicitly get the parameter value from your request url.
public ActionResult SingleSignOn(string action)
{
var querystring = Request.QueryString["action"];
// Do something with querystring
return RedirectToAction("Index");
}
I am customizing this MVC ViewService example of IdentityServer3.
I am trying to add a custom action in LogonWorkflowController where data will be submitted by post request from Login page.
I added a new route in RouteConfig
routes.MapRoute(name: "ResetPasswordSend", url: "send/me/smth",
defaults: new { controller = "LogonWorkflow", action = "Send" });
and I added a new Action in LogonWorkflowController
[HttpPost]
public ActionResult Send(MyCustomModell model)
{
<get ClientId?>
....
}
Is it possible to find out ClientId parameter to be able to create a custom answer based this on ClientId?
Thanks.
Here is the answer to my question (with reference to the code MVC ViewService example):
When Login action of LogonWorkflowController is called, we can get client ID from the message variable and pass it into ViewBag.
ViewBag.ClientId = message.ClientId;
Then using a hidden field in the Login view or using javascript post we can send this clientId to the required post action. So, client ID becomes available in the post action from the Model.
I don't need to implement this anymore, but I think this is the way I could do it. Just be aware that this request can be faked, so nothing important should rely on the received clientID.
So, I've read through tutorials and books about MVC routing as well as played with it on my projects and come to a pretty solid understanding of how to use it to accomplish what I want to with it.
But, I'm up against something I can't quite figure out yet.
What I want to accomplish is a unique url for each client that doesn't look like "http://mysite.com/client/1". This url would take the browser to the Client Controller, Index action, ClientId = 1...obviously.
What I'd like to do is have a URL like "http://mysite.com/Acme" that would do a database lookup to figure out which client has the unique name of "Acme", and then redirect the request to the Client Controller, Index view and set the ClientId to whatever it is on the client with the name 'Acme'.
The default route keeps catching it and can't handle it.
Any ideas?
I recommend using an Global Action Filter to accomplish this or you can create a route with a static path that will route to your lookup controller (e.g., /lookup/{companyname} will route to your database lookup controller).
How about "http://www.mysite.com/Clients/{ClientName}"
routes.MapRoute(null, "Clients/{ClientName}", new{controller = "Clients", action = "Index"};
public class ClientsController : Controller
{
public ActionResult Index(string clientName)
{
var id = Db.GetClientIdBy(clientName);
// do your redirect...
}
}
Or have I missed the point?
I have a rather archaic login system, and this is part of the login action:
// login action
return RedirectToAction("Action", new {
id = aVal,
name = aName,
// other params
});
It redirects the user to the Action action, and i noticed that name and the other params ended up being part of the final url scheme. I need to pass all those values to Action.
[HttpGet]
public ActionResult Action(int id, string name, ...) {
Is it possible to pass them to Action and having the url like this: /Controller/Action/123.
I need to restrict the Action method to only those who pass through the login action, the long url + query string make it almost impossible to make it through, but is there another more profesional way to do it.
Thanks and greetings to the SO and SE community.
In order to get Restful styled url's you need to setup an appropriate route.
So in your case something like
routes.MapRoute("MyRoute", "MyController/MyAction/{id}/{name}", new { controller = "MyController", action = "MyAction" });
you can see some other examples here
The second part of your question is more vague - you may want to tag your class with an [Authorize] attribute and then override OnAuthorization where you can do any checks. Not sure if this is what you are looking for.
There is an example of this here
I have a page routed like /Comments/Search/3 where i search and display all the comments of the thread "3".
I'm adding a sort function (by date, author etc). What is the best way to handle it? /Comments/Search/3/Sort/Author or /Comments/Search/3?sort=author ?
How do I automatically handle the querystring sort=author as a parameter in MVC?
Thanks
I prefer: /Comments/Search/3?sort=author. The querystring is a good place to pass in programmatic parameters, especially if the parameter (like in this case) is not important for SEO purposes. If the parameter had some semantic meaning as a search term, the first URL would be better.
In a controller method you can use something like this:
public ActionResult Search(int id, string sort)
ASP.NET MVC will automatically wire up querystring values to the parameters of your method.
Use the following route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Comments", action = "Search", id = "" } // Parameter defaults
);
/Comments/Search/3?sort=author will call Search(3, "author")
/Comments/Search/3 will call Search(3, null)
Keep in mind that id is mandatory so this url will fail:
/Comments/Search
ASP.NET MVC will handle that automatically in the query string case. You just add a string sort parameter to your action.
Which is better? Personally, I use the path to control the contents being displayed and querystring to control the presentation (how it's displayed, formatted, ...). So, for sorting, I'd go with the querystring method. But I don't think there's a technical disadvantage in either approach.
Your best bet is to add a routing rule to handle it. There's a handy article on it here:
http://aspalliance.com/1525_ASPNET_MVC_Framework_Part_2_URL_Routing.2
Then your URL would read /Comments/Search/3/Sort/Author