URL Routing in MVC C# - c#

I am defining my application URLs like
domainname.com/storecontroller/storeaction/storename
I want to rewrite like
domainname.com/storecontroller/storename
Actually, I need to skip storeaction from the url, I don't want to do it with querystring with "?" Is there anyway to do it by registering rout config path or any another way?

Yes. You can define action as a default parameter, and match for only specific controllers with a Regex constraint:
routes.MapRoute("<route name>", "{controller}/{storename}",
new
{
action = "storeaction"
},
new
{
controller = "somecontroller1|somecontroller2|somecontroller3",
});
(Action will always have the default value "storeaction")
Note that you need to define this route before the default generic route so it doesn't catch it before this kicks in.

Using Attribute routing
[RoutePrefix("Home")]
public ActionResult HomeController : Controller
{
[Route("{storeName}")]
public ActionResult ProcessStore(string storeName)
{
// to do : Return something
}
public ActionResult Index()
{
// to do : Return something
}
}
[RoutePrefix("Payment")]
public ActionResult PaymentController : Controller
{
[Route("{storeName}")]
public ActionResult ProcessStore(string storeName)
{
// to do : Return something
}
}

Related

.NET 6 best way to differentiate a route in the same controller class

I have an API controller say TestController.
I have the following route definition: api/[controller] on class level and I can call the default get method as follows: .../api/test
I want to have another method in the same controller, I also want to call it with Get and the link should be as follows: .../api/test-abc
What is the best way to differentiate this second method within the same controller class.
For test-abc, you can configure the Route attribute as ~/api/test-abc to override the controller base route. See this link for details.
[Route("api/[controller]")]
public class TestController : ControllerBase
{
public IActionResult Get()
{
// ...
}
[HttpGet]
[Route("~/api/test-abc")]
public IActionResult GetAbc()
{
// ...
}
}
This approach changes only the URL of the "test-abc"-action; all other actions of the controller use the base URL configured on class level.
In .Net 6 by following Minimal API's
app.MapGet("api/test", () =>
{
return "";
});
app.MapGet("api/test-abc", () =>
{
return "";
});
By following Traditional Method
[Route("api")]
public class TestController : ControllerBase
{
[HttpGet("test")]
public IActionResult Get()
{
// ...
return Ok();
}
[HttpGet("test-abc")]
public IActionResult GetAbc()
{
// ...
return Ok();
}
}
You can by defining the controllers route template like as below:
[Route("api/[controller]")]
public class TestController : Controller
{
...
}
So you can define a method like:
[HttpGet]
[Route("~/api/Test/Index")]
public IActionResult Index()
{
return Foo.Bar();
}
[HttpGet]
[Route("~/api/Test/Index2")]
public IActionResult Index2()
{
return Foo.Bar2();
}
[HttpGet]
public IActionResult Index3()
{
return Foo.Bar3();
}
You can call it by ../api/test/index2 to use the method Index2 or ../api/test to use Index3.
This is for the standardized way to do, in your case you would use - instead of / at the Route("...") attribute.
If you use - you need to call ../api/test-index2
For further information take a look at documentation.

Setting default route in C# MVC

I am creating a project in C# MVC and was using actions. Due to the requirements, now I am using Route to hide the controller name and display just the page name.
route config
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Law",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Law", action = "Home", id = UrlParameter.Optional }
);
controller 1 (to access this : http://localhost:17920/dashboard) and (http://localhost:17920/alert)
public class LawController : Controller
{
[Route("dashboard")]
[ActionName("Home")]
public ActionResult Home()
{
return View();
}
[Route("alert")]
[ActionName("alert-list")]
public ActionResult AlertList()
{
return View();
}
controller 2 (to access this : http://localhost:17920/list)
public class ListController : Controller
{
[Route("list")]
[ActionName("list-of-return")]
public ActionResult listOfReturn()
{
return View();
}
What I am trying is when I enter this http://localhost:17920 as a default URL, then http://localhost:17920/dashboard should be displayed by default.
Thanks.
You need to define RoutePrefix over the Controller like below. Also update your Route("dashboard") to Route("Home") because that is your default action name on route configuration.
[RoutePrefix("Law")]
public class LawController : Controller
{
[Route("Home")]
[ActionName("Home")]
public ActionResult Home()
{
return View();
}
// Other action methods
}
Please also refer https://devblogs.microsoft.com/aspnet/attribute-routing-in-asp-net-mvc-5/ for more details.
Edit As per edit in your question it is more clear what you want. From your existing code you just need to add one more Route over LawController's Home action as below, so it could match http://localhost:17920/ & http://localhost:17920/dashboard to that action method.
public class LawController : Controller
{
[Route("")]
[Route("dashboard")]
[ActionName("Home")]
public ActionResult Home()
{
return View();
}
[Route("alert")]
[ActionName("alert-list")]
public ActionResult AlertList()
{
return View();
}

Create url link to a controller from another controller

I develop a WebApi RESTful in ASP.NET Core 2.0.
From an action method in a controller A I want to create the URL address for an action method located in a different controller B:
[Route("api/applications/{idbcon}/bcontrollers")]
public class BController : Controller{
[HttpGet({idbcon}), Name = "ActionB"]
public IActionResult ActionB(int idbcon, [FromHeader(Name = "Accept")] string mediatype){
return OK();
}
}
[Route("api/applications/{idapp}/bcontrollers/{idbcon}/acontrollers")]
public class AController: Controller{
[HttpGet(), Name = "GetURLBController"]
public IActionResult GetURLBController()
{
var url = /* Here I would like to get the link to "ActionB" that belong to a Controller "BController" */;
return Ok(url);
}
}
Any advice ???
Use the IUrlHelper.Action overload that takes action and controller parameters:
public class AController : Controller
{
[HttpGet]
public IActionResult GetURLBController()
{
var url = Url.Action("ActionB", "BController");
return Ok(url);
}
}
IUrlHelper is something you inherit from the Controller base class, exposed as the Url property.

How to pass data to controller's field from URL?

I know how to send data to controller's action method as parameter from URL. Here I wonder how can I send data from URL to controller's field?
public MyAwesomeController : Controller {
public string SectionCode { get;set; }
}
and let's define Routes :
routes.MapRoute(
name : "AwesomeRouter",
url : "{code}/{action}",
defaults: new {controller = "MyAwesome", action = "Index", /* What to do here?*/}
);
I want SectionCode be filled with the {code} from URL. Is it possible to implement?
Yes it is, you can create inherited class from basic Controller class and override OnActionExecuting method where you can read url, route or any form data and store them in session or directly fill any field you need. Then create an inherited class of your controller.
public class MyAwesomeController : MyControllerBase
{
public ActionResult Index()
{
//this.SectionCode is available populated here
return View();
}
}
public class MyControllerBase : Controller
{
public string SectionCode
{
get;
private set;
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
this.SectionCode = filterContext.RequestContext.RouteData.Values["code"].ToString();
base.OnActionExecuting(filterContext);
}
}
Each time you hit any action in this controller using route definition you provided, field will be automatically populated. But when you will have more than one route defined they it could get easily into conflicts eg. when code will match to any controller name. Normal website should not work this way.
Your route should look like this:
routes.MapRoute(
name: "AwesomeRouter",
url: "{code}/{action}",
defaults: new { controller = "MyAwesome", action = "Index" }
);
The code should then be passed on to the action as a parameter. I am storing it in the view bag for explanation purposes:
public class MyAwesomeController : Controller
{
public ActionResult Index(string code)
{
ViewBag.Code = code;
return View();
}
}
Using this URL then:
http://somehost/4567/Index
If you access the Viewbag property in your view:
#ViewBag.Code
You should see:
4567

How to parse query string MVC3

I have an url like this:
http://localhost:9562/Account/LogOn?ReturnUrl=%2fCabinet%2fCabinet
I need to parse it to this:
Cabinet/Cabinet
I've looked through
this and this but i can't understand how to use it with my example.
The easiest way would be to accept it as a parameter in your LogOn action:
public class AccountController : Controller
{
public ActionResult LogOn(string ReturnUrl = "")
{
}
}
Note, providing a default value (i.e. = "") allows the action to execute even if the query parameter isn't present in the request.
Alternatively, you could access it through the Request property of your controller:
public class AccountController : Controller
{
public ActionResult LogOn()
{
string request = this.Request.QueryString["ReturnUrl"];
}
}
Try this:
string r = Request.QueryString["ReturnUrl"].Substring(1);
Response.Write(r);

Categories

Resources