How to prevent Browser returning default value of int when input is an int parameter in the URL? - asp.net-mvc-4

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

Related

asp.net core maproute template with string concatenate to action

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

Route Attribute not working in Web API 2

I have two GET methods on my API controller. When I attempt to call the GetByCompanyId method, which I have decorated with the Route Attribute, the request instead is being routed to the GetById method. Below are the relevant code files.
global.ascx.cs
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
webApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.EnableCors();
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
route.config
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
CompanyFunctionsController.cs
public IHttpActionResult GetById(int id)
{
var companyFunction = this._service.GetByKey(new object[] { id });
if (companyFunction != null)
{
var companyFunctionDto = Mapper.Map<CompanyFunctionDto>(companyFunction);
return Ok(companyFunctionDto);
}
return NotFound();
}
[Route("CompanyFunctions/GetByCompanyId", Name = "GetByCompanyId")]
[HttpGet]
public IEnumerable<CompanyFunctionDto> GetByCompanyId(int id)
{
var collection = this._service.GetAll().ToList().Where(x => x.CompanyId == id);
IEnumerable<CompanyFunctionDto> collectCompanyFunctionDtos = Mapper.Map<IEnumerable<CompanyFunctionDto>>(collection);
return collectCompanyFunctionDtos;
}
My HTTP request:
http://localhost:1317/api/CompanyFunctions/GetByCompanyId?id=1
If you want to have a route that starts with api like http://localhost:1317/api/CompanyFunctions/GetByCompanyId?id=1 then you must use the string api in your route attribute that you want it to go to.
[Route("api/CompanyFunctions/GetByCompanyId", Name = "GetByCompanyId")]
Otherwise it will only match based on the http verb (Get in this case).
Alternatively you can decorate the web api controller with the [RoutePrefix("api/CompanyFunctions")] attribute as well and change your Route attribute to [Route("GetByCompanyId", Name = "GetByCompanyId")]
Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API
You might use Attribute Routing in Web Api to solve your problems. Your Controller Action should be like this,
[Route("CompanyFunctions/GetByCompanyId/{companyId}"]
public IEnumerable<CompanyFunctionDto> GetByCompanyId(int companyId)
{
var collection = this._service.GetAll().ToList().Where(x => x.CompanyId == companyId);
IEnumerable<CompanyFunctionDto> collectCompanyFunctionDtos = Mapper.Map<IEnumerable<CompanyFunctionDto>>(collection);
return collectCompanyFunctionDtos;
}
and your HTTP request is http://localhost:1317/CompanyFunctions/GetByCompanyId/1

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);
}
}

MVC 4 creating slug type url

i am trying to create a stackoverflow like url.
I the following example works fine. But if i remove the controller then it errors out.
http://localhost:12719/Thread/Thread/500/slug-url-text
Note the first Thread is the controller the second is the action.
How can i make the above URL look like the following excluding the controller name from the url?
http://localhost:12719/Thread/500/slug-url-text
My Routes
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", // Route name
"{controller}/{action}/{id}/{ignoreThisBit}",
new
{
controller = "Home",
action = "Index",
id = "",
ignoreThisBit = ""
}); // Parameter defaults )
}
}
Thread Controller
public class ThreadController : Controller
{
//
// GET: /Thread/
public ActionResult Index()
{
string s = URLFriendly("slug-url-text");
string url = "Thread/" + 500 + "/" + s;
return RedirectPermanent(url);
}
public ActionResult Thread(int id, string slug)
{
return View("Index");
}
}
Placing the following route before the default route definition will directly call the 'Thread' action in 'Thread' controller with the 'id' and 'slug' parameter.
routes.MapRoute(
name: "Thread",
url: "Thread/{id}/{slug}",
defaults: new { controller = "Thread", action = "Thread", slug = UrlParameter.Optional },
constraints: new { id = #"\d+" }
);
Then if you really want it to be like stackoverflow, and assume someone enters the id part and not the slug part,
public ActionResult Thread(int id, string slug)
{
if(string.IsNullOrEmpty(slug)){
slug = //Get the slug value from db with the given id
return RedirectToRoute("Thread", new {id = id, slug = slug});
}
return View();
}
hope this helps.

MapRoute for overload Action

I have this Controller :
public class ProfileController : Controller
{
public ActionResult Index( long? userkey )
{
...
}
public ActionResult Index( string username )
{
...
}
}
how can i define MapRoute for this actions work like this:
mysite.com/Profile/8293378324043043840
this must be go to first action
mysite.com/Profile/MyUserName
this must be go to second action
I have this route for the first action
routes.MapRoute( name: "Profile" , url: "Profile/{userkey}" , defaults: new { controller = "Profile" , action = "Index" } );
do i need add another MapRoute ? or can i change the current MapRoute for both action?
First you cannot overload controller actions if you are using the same Http Verb (in your case GET) because you need to have unique action names.
So you need to name your actions differently:
public class ProfileController : Controller
{
public ActionResult IndexKey( long? userkey )
{
...
}
public ActionResult IndexName( string username )
{
...
}
}
Or you can use the ActionNameAttribute to give different names to your actions:
public class ProfileController : Controller
{
[ActionName("IndexKey")]
public ActionResult Index( long? userkey )
{
...
}
[ActionName("IndexName")]
public ActionResult Index( string username )
{
...
}
}
Then you will need two routes with using route constraints on the userkey to be a numeric value to setup your actions:
routes.MapRoute(name: "Profile", url: "Profile/{userkey}",
defaults: new { controller = "Profile", action = "IndexKey" },
constraints: new { userkey = #"\d*"});
routes.MapRoute(name: "ProfileName", url: "Profile/{userName}",
defaults: new {controller = "Profile", action = "IndexName"});