asp.net core maproute template with string concatenate to action - asp.net-core

I have a HelloController
When i input URL with http://localhost/Hello/1234
How Could i link to the W1234
I try to modify maproute template like
template: {controller}/W{action}
But it didn't work
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Hello",
template: "{controller}/{action}/{id?}");
});
public partial class HelloController : Controller
{
public IActionResult W1234()
{
return View();
}
}

You could try to use Attribute routing uses a set of attributes to map actions directly to route templates.
[[Route("Hello/1234")]
public IActionResult W1234()
{
return View();
}
Attribute routing can also make use of the Http[Verb] attributes such as HttpPostAttribute. All of these attributes can accept a route template.
[HttpGet("/Hello/1234")]
public IActionResult W1234()
{
return View();
}
Reference : Routing to controller actions in ASP.NET Core

Related

Why does my default action method return a 404?

I have the following .NET Core 2.2 API controller
public class TestController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok(1);
}
[HttpGet]
[ExactMatch("id")]
public IActionResult Get([FromRoute]int id)
{
return Ok(id);
}
}
And this is my route definition:
app.UseMvc(
routes =>
{
routes.MapRoute("default", "api/{controller}/{action=Get}/{id?}");
}
);
}
The following URLs work fine:
https://localhost:44305/api/test
https://localhost:44305/api/test/get/5
but not this one
https://localhost:44305/api/test/5 /* Notice the missing action method*/
It returns a 404 error
Could anybody help me figure out what I am missing?
Try the public class TestController inherited from Controller, not from ControllerBase and in the Route, you should specify which controller you are calling, like:
routes.MapRoute("default", "{controller=Test}/{action=Get}/{id?}");
First Replace
[ExactMatch("id")]
to
[HttpGet("id")]
Secondly replace
app.UseMvc(
routes =>
{
routes.MapRoute("default", "api/{controller}/{action=Get}/{id?}");
}
);
}
to
app.UseMvc(
routes =>
{
routes.MapRoute("default", "api/{controller}/{action}/{id?}");
}
);
}

How to prevent Browser returning default value of int when input is an int parameter in the URL?

public IActionResult Info(int id)
{
return Content(id + "");
}
Whenever I input Jan/Info/2 the browser returns me the value 0. Why is this and how can I fix this? I'm using MVC core 1.1. UrlParameter.Optional is also not present in Visual Studio for some reason it's not accessible.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Naam",
template: "{controller=Jan}/{action}/{voornaam}");
routes.MapRoute(
name: "Info",
template: "{controller=Jan}/{action}/{id}");
}
public IActionResult Naam(string voornaam)
{
return Content(voornaam);
}
Because you already have another route registration which is matching the exact pattern. As per that registration, it will read the value and assign to the voornaam parameter.
So this should work
public IActionResult Info(int voornaam)
{
return Content(voornaam + "");
}
Since you have unique names for your action method, you do not need to specify the custom routes for each action method. The default route registration will work fine.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "defaultroutes",
template: "{controller}/{action=Index}/{id?}",
defaults: new { controller = "jan" });
});
Assuming your controller looks like this
public class JanController : Controller
{
public IActionResult Info(int id)
{
return Content(id + " : id");
}
public IActionResult Naam(string voornaam)
{
return Content(voornaam+ ": param value");
}
}
When you access yourSite/jan/info/123, The Info method will handle that and when you request yourSite/jan/Naam?voornaam=shyju ,the Naam method will handle that.
If you want to support url structure like yourSite/jan/Naam/shyju instead of the explicit querystring, you can specify a route pattern on that action method with attribute routing
public class JanController : Controller
{
public IActionResult Info(int id)
{
return Content(id + " id");
}
[Route("[controller]/[action]/{voornaam}")]
public IActionResult Naam(string voornaam)
{
return Content(voornaam + " : param value");
}
}
Now when you request yourSite/jan/Naam/shyju, The Naam method will be called and the string "shyju" will be available in the voornaam parameter

Defalut routing not working after adding route attribute in asp.net mvc

I created an mvc project with no attribute route. It was working fine. When I added an attribute route [Route("employeehome")] on one of my action methods, the conventional routing {controller}/{action}/{id} ie employee/index for that method ceased working. Is there anything wrong with my approach?
Adding my code snippet.
Route Config Code.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Controller code.
public class EmployeeController : Controller
{
// GET: Employee
[Route("employeehome")]
public ActionResult Index()
{
return View();
}
}

ASP MVC default route is not applying for root site url

I'm having trouble getting ASP.net MVC to serve up the default controllers index view for the root site url http://mysite:8080/. All I get back is a 404 with The resource cannot be found. It works fine if I specify the full route path in the url : http://mysite:8080/Default/Index, however, I want the default route to apply even if the user doesn't specify the route path though. It seems that this should just work out of the gate. This is a fresh project from the VS2013 MVC 4 template.
I've tried both route mappings below and neither seems to work. How can this be achieved?
routes.MapRoute(
"Root",
"",
new { controller = "DefaultController", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "DefaultController", action = "Index", id = UrlParameter.Optional }
);
Here is a solution to this problem. It's disappointing that the default route's defaults do not apply for the root site url though.
routes.Add(new Route("", new SiteRootRouteHandler("~/Default/Index")));
public class SiteRootRouteHandler : IRouteHandler
{
private readonly string _redirectUrl;
public SiteRootRouteHandler(string redirectUrl)
{
_redirectUrl = redirectUrl;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new SiteRootHandler(_redirectUrl);
}
}
public class SiteRootHandler: IHttpHandler
{
private readonly string _redirectUrl;
public SiteRootHandler(string redirectUrl)
{
_redirectUrl = redirectUrl;
}
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.RedirectPermanent(_redirectUrl);
}
}

Have Microsoft changed how ASP.NET MVC deals with duplicate action method names?

I might be missing something here, but in ASP.NET MVC 4, I can't get the following to work.
Given the following controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string order1, string order2)
{
return null;
}
}
and it's view:
#{
ViewBag.Title = "Home";
}
#using (Html.BeginForm())
{
#Html.TextBox("order1")<br />
#Html.TextBox("order2")
<input type="submit" value="Save"/>
}
When start the app, all I get is this:
The current request for action 'Index' on controller type
'HomeController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Index() on type
ViewData.Controllers.HomeController System.Web.Mvc.ActionResult
Index(System.String, System.String) on type
ViewData.Controllers.HomeController
Now, in ASP.NET MVC 3 the above works fine, I just tried it, so what's changed in ASP.NET MVC 4 to break this?
OK there could be a chance that I'm doing something silly here, and not noticing it.
EDIT:
I notice that in the MVC 4 app, the Global.asax.cs file did not contain this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
which the MVC 3 app does, by default. So I added the above to the MVC 4 app but it fails with the same error. Note that the MVC 3 app does work fine with the above route. I'm passing the "order" data via the Request.Form.
EDIT:
In the file RouteConfig.cs I can see RegisterRoutes is executed, with the following default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
I still get the original error, regards ambiguity between which Index() method to call.
Because MVC4 ships with ASP.Net Web.API you can potentially reference two HttpPostAttribute (the same applies to the other attributes like HttpGet, etc.):
System.Web.Mvc.HttpPostAttribute is used by ASP.Net MVC so you need to use it on actions inside Controller derived controllers
System.Web.Http.HttpPostAttribute is used by ASP.Net Web.API so you need to use it on actions inside
ApiController derived controllers
You have acidentally referenced System.Web.Http.HttpPostAttribute in your code. Change it to use the right attribute and it should work correctly:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[System.Web.Mvc.HttpPost]
public ActionResult Index(string order1, string order2)
{
return null;
}
}