Best way to give each customer a custom vanity URL - asp.net-mvc

I allow each customer to choose their own URL, by baking their own custom code into the url as the first segment after the domain like this (https://www.[mydomain].com/customercode) and then learn who they are from that URL. This is working fine by learning who they are using MVC routing and session. The problem is that once the customer begins their session using their custom URL, the URL changes and they no longer see their name in the URL. i.e. they start the session as https://www.[mydomain].com/customercode, then the URL changes to something like https://www.[mydomain].com/account/login after the first re-direct.
Is there a way for me to preserve that customer info segment of the URL and just consider it as part of 'the base url'?
In the past I have written extensions such as CustomActionLink and CustomAction functions to override standard url rendering but that would mean that I need to use those functions all over my site. I am wondering if I manipulate or dictate every url rendered by my site, so that the customer name always appears in their url bar.
For reference, here is my routing code
// https://scheduler.[theservicedomain].com/TheCustomersName
routes.MapRoute(
name: "Scheduler",
url: "{practiceRouteCode}",
defaults: new { controller = "Scheduler", action = "Index" }
);
// https://scheduler.theservicedomain].com/scheduler/selectservice
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Scheduler", action = "Index" },
namespaces: new[] { "Scheduler.Controllers" }
);
//https://scheduler.theservicedomain].com/TheCustomersName/scheduler/selectdate
routes.MapRoute(
name: "VanityURL",
url: "{practiceRouteCode}/{controller}/{action}",
defaults: new { controller = "Scheduler", action = "Index" },
namespaces: new[] { "Scheduler.Controllers" }
);
The customer is always required to begin the session with the first or third route, then we know who they are. But as of now the customer information (practiceRouteCode) is dropped and the rest of the session is on the second (Default) route.

Related

Custom route, which doesn't display the Action in the link

I am trying to code a route in route config, which will give me tha chance to use this format http://localhost:port/Account/1 rather than this http://localhost:port/Accounts/Details/1.
My code for this is the following :
routes.MapRoute(
name: "Account",
url: "Account/{id}",
defaults: new { controller = "Accounts", action = "Details"}
);
Sadly, this give me :
Server Error in '/' Application.
The resource cannot be found
Any tips on how to make this work will be appreciated.

MVC Routing Parameter Precedence

I came across a scenario where I had the default MVC Route setup. Like So.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Then navigating to a url as such
domain/controller/action/1234
On this page I was then navigating to the same page but with different parameters after a certain event. Like so.
var id = $(this).data("id");
var url = "#Url.Action("action", "controller", new { area = ""})";
var params = $.param({id: id, vrnsearch: true});
var fullUrl = url += "?" + params;
window.location.href = fullUrl;
I noticed that the url was still keeping the same id in the url and attaching parameters like so.
domain/controller/action/1234?id=4321&vrnsearch=true
Now my question is, is there a way to determine a precedence over if it should use the value for id from the url or from the parameter.
I have actually found a work around/fix for my issue by using the below, which removes the id from the url and just uses parameters.
#Url.Action("action","controller", new {id = "", area = ""})
However was just curious if there is a precedence in parameters vs url routing.
The query string has nothing at all to do with routing (at least, not unless you customize routing to consider it).
The values that are passed to the ModelBinder and to your action method are done so by Value Providers. You can control the order of precedence by changing the order in which their corresponding ValueProviderFactory is registered in the static ValueProviderFactories.Factories property.
As you can see, the default configuration is to first use the RouteDataValueProviderFactory and if it returns no value it will try the QueryStringValueProviderFactory. If you change the order of the factories, the order of precedence changes.
ValueProviderFactories.Factories.RemoveAt(3);
ValueProviderFactories.Factories.Insert(4, new RouteDataValueProviderFactory());

MVC Routing Removes Parameters

My current routing configuration looks as follows:
routes.MapRoute(
namespaces: new string[] { "ChiDesk.WebUI.Controllers" },
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The problem I'm running into is that if I link to the below address:http://localhost:20220/Public/Book?id=c231e3aa-a317-4321-88ef-fe989356babc
The routing appears to remove the id parameter part. So the address in the browser is set to:
http://localhost:20220/Public/Book
This obviously causes a problem if you refresh the page as the id parameter is not included anywhere.
What do I need to change on my routing to sort this out?
Thanks,
Gary
My mistake.
On my document ready function I was setting the history using replaceState. However I was using window.location.pathname property which does not include parameters.
Changing it to window.location has sorted this out.

MVC routes.MapRoute name property

I'm brand new to MVC so please bear with me as I'm only on the second page of the MS Tutorial (see last code example). For the HelloWorldController the following MapRoute is added:
routes.MapRoute(
name: "Hello",
url: "{controller}/{action}/{name}/{id}");
I'm just wondering, is it purely the pattern matching that does the work and the name "Hello" is just for my own reference? If so, are there not naming conventions that should be followed saying the MapRoute should be called HelloWorldWelcome, where welcome is a method inside the HelloWorldController.cs (see above link). Or am i being pedantic?
The route name is also used by the UrlHelper class. For example:
var url = Url.Route("Hello", new
{
controller = "SomeController",
action = "SomeAction",
name = "charlie",
id = 123
});
This will generate a matching URL.
This feature is much more useful when you use Attribute Routing. For example, if on some controller you have an action:
[RoutePrefix("api/phonebook")]
public class PhonebookController
{
[HttpGet("contact/{id}", Name = "GetContact")]
public Contact GetContact(int id)
{
...
}
}
In other code you could use Url.Route("GetContact", new { id = 7 }) to generate the URL /api/phonebook/contact/7.
Please refer to details on ASP.NET MVC Routing Overview
Name attribute is for callign a route from your views or controller with route name.
From ActionLink your can use a routename:
Html.RouteLink("link_text", "route_name", route_parameters)
The question seems to be not so clearly answered (how the "Hello" route is choosen by the "HelloWorld" controller?), but as an Asp.Net MV5 begginer, I can see that the route is selected by default according to the match between the router url property and the URL parameters.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ImageScan", action = "ScanImage", id = UrlParameter.Optional },
namespaces: new[] { "WebApplication3.Controllers" }
);
I am finding error :
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Views/ImageScan/ScanImage.cshtml

Default Routing Not working in .NET MVC 1 (and 2)

My default routes are very simple, but the page doesn't properly load without fully qualifying the entire route.
Here are the routes I'm using:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index" } // Parameter defaults
);
Here's the only action in the application in a HomeController:
public ActionResult Index()
{
return Content("New stuff");
}
With these URLs:
http://localhost:8081/NewMvc1/
I get The incoming request does not match any route.
With:
http://localhost:8081/NewMvc1/Home
http://localhost:8081/NewMvc1/Home/Index
I get a 404 Mvc page that says it tried to handle the request with a static file.
Yet, finally with a 'fully qualified url'
http://localhost:8081/NewMvc1/Home/Index/1
I get the expected result output from the one and only one action.
New Stuff
This doesn't seem right at all. I've also been getting Failed to Execute Action from this same application (not sure if that's related).
I've used Phil Haack's RouteDebugger to get this far, which pointed out that it wasn't matching the URL when the Optional parameters were missing, but did when those parameters were provided.
You're missing the id from your defaults:
new { controller = "Home", action = "Index", id = UrlParameter.Optional }

Resources