Route map in JSF - jsf

Im building a site with JSF and i need to have the following urls:
www.---.com/domain1/page.jsf
www.---.com/domain2/page.jsf
...
www.---.com/domainN/page.jsf
In ASP.NET i was able to do that this way:
routes.MapRoute(
name: "Default",
url: "{domain}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
I have tried using http://www.ocpsoft.org/rewrite/ like this:
.addRule(Join.path("/{domain}/clients/{page}").to("/clients/{page}.jsf"));
but the effect its not the same.
For example when redirecting to another page inside a beans method with:
return "page?faces-redirect=true";
the url generated by that does not contain the domain part. I cant also get the domain part from the request url because its not there.
How else can i achieve this?
Thanks

Related

MVC 5 Pretty URL

Hi there
I'm working on a system where I have been asked to change the URL in the address line.
To take the short version, we have a profile page for all our lorries, let's say we have a lorry named SuperTransport, so I've made a routing that allows us to access his profile page by typing http: //app.fragtopgaver.dk/SuperTransport, problems are now that when you come to his profile page, something else says in the URL, which says http://app.fragtopgaver.dk/getindex/?slug=supertransport
I need that it still says http://app.fragtopgaver.dk/SuperTransport in the URL when landing on the page.
My routing looks like this:
routes.MapRoute(
name: "slug",
url: "{slug}",
defaults: new { controller = "Home", action = "show" },
constraints: new { slug = ".+" });
And in my Home Controller
public async Task<ActionResult> Show(string slug)
{
return RedirectToRoute(ProfileControllerRoute.GetIndex, new { slug = slug});
}
and my Profile Controller
[Route("GetIndex", Name = ProfileControllerRoute.GetIndex)]
public ActionResult Index(int? page, string slug = null)
Hope someone can give me a hint of what i can do about this.
The Answer was really simple, just had to add
[Route("{slug}")]
to the controller

MvcSiteMapProvider Sitemap.xml endpoint breaks with custom route

I have a custom route to simplify the url and only use the home controller implicitly, but by doing so I can no longer access my sitemap.xml form the default endpoint, how could I fix this?
'routes.MapRoute(
' name:="OmitController",
' url:="{action}/{id}",
' defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional}
')
Nevermidn I looked at the source code and saw that the default route for the sitemap.xml is calling the XmlSiteMap and the Index action so I added this
routes.MapRoute(
"sitemap",
"sitemap.xml",
New With {.controller = "XmlSiteMap", .action = "Index"}
)
and it works now

Custom routes and namespaces in MVC5

I'm trying to implement some domain name logic in my existing MVC5 app. The problem I'm running in to is if I try to use my custom subclass from Route, it doesn't respect the Namespaces field and throws an error because I have 2 different User controllers.
As a control, this works perfectly fine:
routes.MapRoute("Login",
"login/",
new { controller = "User", action = "Login" },
new[] { "Quotes.Web.Controllers" });
My DomainRoute class inherits from Route and just adds a Domain property. Here is the relevant constructor:
public DomainRoute(string domain, string url, object defaults, string[] namespaces = null)
: base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
Domain = domain;
DataTokens = new RouteValueDictionary {["Namespaces"] = namespaces};
}
and I register it like:
var loginRoute = new DomainRoute(
domain,
"login/",
new { controller = "User", action = "Login" },
new[] { "Quotes.Web.Controllers" });
routes.Add("Login", loginRoute);
DataTokens looks identical between the working version and my broken version yet it seems to ignore the fact that my DomainRoute has a Namespace entry
Multiple types were found that match the controller named 'User'. This can happen if the route that services this request ('login/') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
What am I missing?
I think,this will help you, i had the same issue, solved this by adding the below code
var dataTokens = new RouteValueDictionary();
var ns = new string[] {"MyProject.Controllers"};
dataTokens["Namespaces"] = ns;
routes.Add("Default", new CultureRoute(
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
null /*constraints*/,
dataTokens
));
I switched my DomainRoute class with the much improved version found here: https://gist.github.com/IDisposable/77f11c6f7693f9d181bb
Now my route creation is just:
var clientRoutes = new DomainRouteCollection("mydomain",
"Quotes.Web.Controllers",
routes);
clientRoutes.MapRoute("Login", "login/", new { controller = "User", action = "Login" });
...which is more concise and even more importantly, it works.

MVC5 Rewriting Routing Attribute - Default page

I am attempting to switch from RouteConfig to Routing Attributes.
I am following along the Pro ASP.NET MVC 5 book from Adam Freeman and I'm trying to convert the following code that handles the paging of clients.
routes.MapRoute(
name: null,
url: "{controller}/Page{page}",
defaults: new { action = "Index", status = (string)null },
constraints: new { page = #"\d+" }
);
This works great! As I go to different URLs, the links look very nice
http://localhost:65534/Client - Default page
http://localhost:65534/Client/Page2 - Second page
Now I've decided to try out Url Attributes and having a bit of problems when it comes to how 'pretty' the links are. All of the links are working fine, but it's the 'routing rewriting' that I am trying to fix.
Here are the important parts of my controller.
[RoutePrefix("Client")]
[Route("{action=index}/{id:int?}")]
public class ClientController : Controller {
[Route("Page{page:int?}")]
public ActionResult Index(string sortOrder, string search = null, int page = 1) {
With the attribute above the Index, going to /Client or to /Client/Page gives me a 404.
Adding a blank route to catch the default page
[Route("Page{page:int?}")]
[Route]
Works for /Client and /Client/Page3, but now the rewriting of the URL is messed up. Clicking on page 3 of the pager gives me a URL of
http://localhost:65534/Client?page=3
which is not what I want. Changing the routing to
[Route("Page{page:int?}")]
[Route("{page=1:int?}")]
Works almost 100%, but the default link for /Client is now
http://localhost:65534/Client/Page
So, I am now asking for help. How can I correctly convert the original MapRoute to the attributes?
Just use:
[Route("", Order = 1)]
[Route("Page{page:int}", Order = 2)]
UPDATE
Plainly and simply, the routing framework is dumb. It doesn't make decisions about which route is the most appropriate, it merely finds a matching route and returns. If you do something like:
Url.Action("Index", "Client", new { page = 1 })
You're expecting the generated URL to be /Client/Page1, but since you have a route where page is essentially optional, it always will choose that route and append anything it can't stuff into the URL as a querystring, i.e. /Client?page=1. The only way to get around this is to actually name the route you want and use that named route to generate the URL. For example:
[Route("", Order = 1)]
[Route("Page{page:int}", Name = "ClientWithPage", Order = 2)]
And then:
Url.RouteUrl("ClientWithPage", new { page = 1 })
Then, you'll get the route you expect because you're directly referencing it.
UPDATE #2
I'm not sure what you mean by "go into PagedList.MVC and add a name property to it". It doesn't require any core changes to the code because PagedList already has support for custom page links. Just change your pager code to something like:
#Html.PagedListPager((IPagedList)ViewBag.OnePageOfItems, page => Url.RouteUrl("ClientWithPage", new { page = page }))
And you'll get the URL style you want. Attribute routing can be a bit more finicky than traditional routing, but I'd hardly call it useless. It's far more flexible than traditional routing, but that flexibility has some costs.

MVC 5 AttributeRouting Catch All

How do I create a catch all route with the new Attribute routing in MVC
I tried this:
[Route("{pagenode}", Order = 999)]
But when I have a named route like
[Route("contact"]
I get the "Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL." error.
This can be done with Attribute Routing if the first "directory" in the path is fixed.
For example, to match anything that hits /questions or /questions/4 or /questions/answers/42 then you would use [Route("questions/{*catchall}"].
You can't do this with Attribute routing, do this the MVC4 way:
Map a route in your routemapper like this:
routes.MapRoute("RouteName","{*url}",new { controller = "YourFancyController", action = "YourAction" });
This will be your catch-all Route.
If you would like to map all the routes to their controller you can do this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
The ability to do this must have changed.
In my default controller, still called 'Home' I have one result method which I want executed for an unrecognised URL structure. The routing attribute is: [Route("{*catchall}")]. This is successfully executed for any old thing.
I have a second method which is always successfully executed based on its route (and I've thrown a few route 'styles' at it to see if it always works). I can only assume that the framework always registers the catch-all route last as this is the behaviour I'm seeing.
This is also a brand new, not configured (except for nuGet packages) MVC 5 project excepting that my methods have been changed to return JsonResult (not even doing their job yet but returning little anonymously typed objects). The catch-all for example returns: Json(new { Message = "Invalid Request" }, JsonRequestBehavior.AllowGet). Yes, yes I set the StatusCode first etc etc, this isn't about MY project ;).
I'm sure I haven't left anything out since there's so little to it but if any clarification is wanted I'll see about adding it.

Resources