0

I am having a hard time wrapping my head around custom routing in MVC Core. I get that I need to add something here in Startup

app.UseMvc(routes =>
{
    routes.MapRoute(
       name: "default",
       template: "{controller=Home}/{action=Index}/{id?}");
});

But how am I supposed to get a controller to function properly? I basically need a data details view to pull up using a string instead of an id. So "string url" instead of "int id".

I read some articles online but everything I tried seemed to fail. Thanks in advance.

4 Answers 4

1

You should be fine by adding a route constraint, telling your code, that id will be a string (word);

app.UseMvc(routes =>
{
    routes.MapRoute(
       name: "default",
       template: "{controller=Home}/{action=Index}/{id}",
       defaults: null,
       constraints: new {Id = @"\w+" }); /* \d+ limits to only digits*/
});

Reference: http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-route-constraint-cs

Alternativley you could use AttributeRouting and decorate your controller and action methods with the appropriate Route() annotation:

[Route("api/[controller]")]
public class HomeController : Controller
{
    [Route("[action]/{name}")]
    public string GetSomething(string name)
    {
        return foo;
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help. I was able to get the constraint field to stick by using constraints with the 's' added. Just a note if you want to edit above. This throws an error on build though saying MapRoute does not have an overload method that accepts more than 2 values.
@GregGoodwin Thanks for the hint. From the top of my head I forgot the defaults property. Fixed it
Use inline constraints instead hanselman.com/blog/… it's going to be a lot cleaner
Specifically you can just use :decimal, see this class - github.com/aspnet/Routing/blob/…
1

You use route constraints to restrict the browser requests that match a particular route. You can use a regular expression to specify a route constraint.

Comments

0

The correct solution for MVC Core is to add a constraint as follows:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}", 
        defaults: null,
        constraints: new { id = @"\w+" }); /* \d+ limits to only digits*/
});

In order to prevent the compile errors from happening, you need to supply a value for defaults (in this case, null), and also it should be constraints, not constraint. To prevent possible issues down the road, you should also be mindful of the case used for the id parameter.

Comments

0

But how am I supposed to get a controller to function properly?

I only want to underline that this is only one of various options. Routing is used when you want to prettify the url, and manage the third slash in the url. It is the best option when the url is visible, but remember that if you are working on ajax for example you can use directly the querystring without the routing rules: controller/action?id=hello

If your need is a routing rule:

  1. You can modify the default rule to accept also a string in the id parameter, and keep working with a method that accept an 'id'.

  2. Add another rule that accept another parameter named for example 'code' or something that fits well for your methods that use a string research key. A nd customize that new binding on various levels (like the default for all controllers\actions, for a single controller, ...)

  3. You can add that custom rule also using C# Attributes in the controller. (PROS: you have on the method the rule, so is useful to rembember, and you can import in another project the controller and all its routing rules. CONS: on large projects may be difficult understand how will interact rules that are all distributed in various files).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.