Url.RouteUrl not gettting an API route in MVC5 - asp.net-mvc

I created a MVC 5 site using its template and added the following API controller:
namespace MvcSite.Controllers {
public class TestController : ApiController {
[Route("test/send"), HttpGet]
public String Send() {
return "SENT";
}
} // TestController
} // MvcSite.Controllers
When I access "/test/send" I get the string "SENT" back as expected ...
In a Razor view or in a Controller I need to get the URL of the send action so I tried:
var url = Url.RouteUrl(new { controller = "Test", action = "Send", HttpRoute = true });
But url is null ... I have no idea why ...
The API route is working fine so it is in the Route Table ...
What am I missing?
Thank You,
Miguel

Configure a named route and use the HttpRouteUrl method to get the URL.
[Route("test/send", Name = "Send"), HttpGet]
public String Send() {
return "SENT";
}
Get the URL like this:
var url = Url.HttpRouteUrl("Send", new {});

Related

Redirect to specified action if requested action was not found

How can I redirect Action which is not found in controller into another action within the same controller? Let's say that file abc.txt is requested via http://localhost:5000/Link/GetFile/abc.txt. My controller correctly serving that file. But now, i need to handle request such as http://localhost:5000/Link/Document/abc. Of course there is no any action matched to Document so I need to invoke function Error within the same controller (including id from original request).
I tried to solve this with StatusCodePagesWithReExecute function but then my File action is not working (each request goes directly to Error function).
I have following controller:
public class LinkController : ControllerBase
{
public IActionResult GetFile(string id)
{
return DownloadFile(id);
}
public IActionResult Error(string id)
{
return File("~/index.html", "text/html");
}
private FileResult DownloadFile(string fileName)
{
IFileProvider provider = new PhysicalFileProvider(#mypath);
IFileInfo fileInfo = provider.GetFileInfo(fileName);
var readStream = fileInfo.CreateReadStream();
return File(readStream, "text/plain");
}
}
and startup configuration:
app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "application/octet-stream",
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}"
);
});
Any clues how to solve this problem?
Regards
You can use UseStatusCodePages to achieve a simple redirection whenever there's a 404. Here's what it looks like:
app.UseStatusCodePages(ctx =>
{
if (ctx.HttpContext.Response.StatusCode == 404)
ctx.HttpContext.Response.Redirect("/Path/To/Your/Action");
return Task.CompletedTask;
});
Just add this somewhere above UseMvc.
EDIT:
I´m sorry, my first answer was not correct.
IRouteCollection router = RouteData.Routers.OfType<IRouteCollection>().First();
with this, you can match an url to controller action
Create HttpContext for testing (example with injection)
private readonly IHttpContextFactory _httpContextFactory;
public HomeController(
IHttpContextFactory httpContextFactory)
{
_httpContextFactory = httpContextFactory;
}
Create the context with values
HttpContext context = _httpContextFactory.Create(HttpContext.Features);
context.Request.Path = "/Home/Index";
context.Request.Method = "GET";
Check route
var routeContext = new RouteContext(context);
await router.RouteAsync(routeContext);
bool exists = routeContext.Handler != null;
Further reading: https://joonasw.net/view/find-out-if-url-matches-action

How to utilize a user-defined url action in asp,net mvc?

My hope is to provide a method to end users that will let them enter a value 'SmallBuildingCompany', and then use this value to make a custom url that will redirect to an informational view. so for example, www.app.com/SmallBuildingCompany. Can anyone point me to some information to help on this?
edited 161024
My attempt so far:
I added this within RouteConfig.
RouteTable.Routes.MapRoute(
"Organization",
"O/{uniqueCompanyName}",
new { controller = "Organization", action = "Info" }
and added a new controller method and view under the organization controller.
public async Task<ActionResult> Info(string uniqueCompanyName)
{
var Org = db.Organizations.Where(u => u.uniqueCompanyName == uniqueCompanyName).FirstOrDefault();
Organization organization = await db.Organizations.FindAsync(Org.OrgId);
return View("Info");
}
You can achieve this by using the SmallBuildingCompany part of the URL as a parameter for an action that is used to display every informational view.
Set up the Route in Global.asax.cs to extract the company name as parameter and pass it to the Index action of CompanyInfoController:
protected void Application_Start() {
// Sample URL: /SmallBuildingCompany
RouteTable.Routes.MapRoute(
"CompanyInfo",
"{uniqueCompanyName}",
new { controller = "CompanyInfo", action = "Index" }
);
}
Note that this Route will probably break the default route ({controller}/{action}/{id}), so maybe you want to prefix your "Info" route:
protected void Application_Start() {
// Sample URL: Info/SmallBuildingCompany
RouteTable.Routes.MapRoute(
"CompanyInfo",
"Info/{uniqueCompanyName}",
new { controller = "CompanyInfo", action = "Index" }
);
}
Then the CompanyInfoController Index action can use the uniqueCompanyName parameter to retrieve the infos from the database.
public ActionResult Index(string uniqueCompanyName) {
var company = dbContext.Companies.Single(c => c.UniqueName == uniqueCompanyName);
var infoViewModel = new CompanyInfoViewModel {
UniqueName = company.UniqueName
}
return View("Index", infoViewModel);
}
ASP.NET Routing

Using certain parts of URL as params in a Grails Controller

I've created a static URL in Grails:
class UrlMappings {
static mappings = {
...
"/remittance/bank"{
controller={"BankRemittance"}
action=[GET:"index"]
}
"/remittance/bank/$bankId/spd/$spdId"{
controller={"SPD"}
action=[GET:"show"]
}
...
}
}
Now what I want is to retrieve bankId and spdId values of the URL on my SPDController:
class SPDController {
def myService
def show() {
String bankId = ? // code to get bankId from the URL
String spdId = ? // code to get spdId from the URL
render(
view: "...",
model: myService.transact(bankId, spdId)
)
}
}
But how can I do that? It seems using params.bankId and params.spdId is not for this scenario.
Your action should accept the URL parameters as arguments.
def show(String bankId...)

Similar route mapping

I need to map to create controller what must response to two urls:
"http://localhost/api/controller?id=1" (where only id value can change)
"http://localhost/api/controller/anotherId/someconst" (where anotherId is the only one changing part)
i map it to such route:
routes.MapHttpRoute("Test", "api/{controller}/{id}/{someconst}", new { controller = "Test", someconst = RouteParameter.Optional });
And have to methods in my controller:
public void Get(int id) { ... }
public void Get(int anotherId, string someconst ) { ... }
It works...But it doesn't look nice...cause "string someconst" is not a param, it's just a const part of url. But if i remove "string someconst" param second url wouldn't work.
Is it possible to map one controller to two routes to resolve this urls to make it clear without fake param which is a const in fact?
Well i've got the answer...just to have to routes...
routes.MapHttpRoute("Test", "api/{controller}/{id}", new { controller = "Test", action = "Get", id= #"\d+"); );
routes.MapHttpRoute("TestSomeConst", "api/{controller}/{anotherId}/someconst", new { controller = "Test", action = "GetSomeconst", anotherId= #"\d+");
And change controller methods (actions):
public void Get(int id) { ... }
public void GetSomeconst(int anotherId) { ... }
One thing you could try doing is to map the route like this:
routes.MapHttpRoute("Test", "api/{controller}/{id}/{action}", new { controller = "Test", action = "Get", id= #"\d+"} );
and make your actions:
public void Get(int id) { ... }
[HttpGet]
public void Someconst(int id) { ... }
Because your action defaults to the "Get" method, you can ignore that and call it with:
http://localhost/api/test/1
If you wanted to call your other method, you would use
http://localhost/api/test/1/someconst

ASPMvc Routing Issues with legacy url

I have got a legacy url that I cannot change, which is output on a page which needs to now post to a new MVC version of the page:
http://somesite.com/somepage?some-guid=xxxx-xxxx
Now I am trying to map this to a new controller but I need to get the some-guid into my controller:
public class MyController : Controller
{
[HttpGet]
public ActionResult DisplaySomething(Guid myGuid)
{
var someResult = DoSomethingWithAGuid(myGuid);
...
}
}
I can change the controller and routes as much as I like, however the legacy url cannot change. So I am a bit stumped as to how I can get access to the some-guid.
I have tried routing with the ?some-guid={myGuid} but the routing doesn't like the ?, so then I tried to let it autobind, but as it contains hyphens it doesn't seem to bind. I was wondering if there was any type of attribute I could use to hint that it should bind from a part of the querystring...
Any help would be great...
I would have thought you would have done a route a bit like this..
routes.MapRoute(
"RouteName", // Name the route
"somepage/{some-guid}", // the Url
new { controller = "MyController", action = "DisplaySomething", some-guid = UrlParameter.Optional }
);
The {some-guid} part of URL matches your url parmater and passes it to the controller.
So if you have your action like so :
public ActionResult DisplaySomething(Guid some-guid)
{
var someResult = DoSomethingWithAGuid(some-guid);
...
}
Give that a go and see how you get on..
routes.MapRoute(
"Somepage", // Route name
"simepage", // URL with parameters
new { controller = "MyController", action = "DisplaySomething"
);
And then in your controller:
public class MyController : Controller {
public ActionResult DisplaySomething(Guid myGuid)
{
var someResult = DoSomethingWithAGuid(myGuid);
...
}
}
Try this:
routes.MapRoute("SomePageRoute","Somepage",
new { controller = "MyController", action = "DisplaySomething" });
And then in your controller:
public ActionResult DisplaySomething() {
Guid sGuid = new Guid(Request.QueryString["some-guid"].ToString());
}

Resources