Url.Action() does not use good route config - asp.net

I have overridden a default route in my routes configuration :
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyController_OverriddenAction",
"MyController/OverriddenAction",
new { controller = "MyOverriddenController", action = "OverridenAction" },
new[] { "Plugin" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "home", action = "Index", id = UrlParameter.Optional }
);
}
}
If I call MyController/OverriddenAction, the overridden action OverriddenAction in MyOverriddenController is displayed. It works.
But if I call #Html.Action("OverriddenAction", "MyController"), the default route is called.
Why? What is the solution?
My controllers :
public class MyOverridenController : Controller
{
public ActionResult OverriddenAction()
{
return Content("overridden");
}
}
public class MyController : Controller
{
public ActionResult OverriddenAction()
{
return new EmptyResult();
}
[...]
}

You should use following syntax
#Html.Action("OverriddenAction", "MyOverriden")
while calling the method directly like MyController/OverriddenAction it looks for the entry in MapRoute. However, while using #Html.Action you should use the actual controller name.

Related

Route Confusion with Single Action

I am clearly having issue understanding the routes here or trying to achieve which is not possible.
I have this in my RouteConfig:
routes.MapRoute(
name: "Explorer",
url: "{controller}/{action}/{prefix}/{value}",
defaults: new { controller = "Explorer", action = "Index", prefix ="", value = UrlParameter.Optional }
);
And in Explorer Controller I have the following:
[RoutePrefix("Explorer")]
public class ExplorerController : Controller
{
public ActionResult Index()
{
return View();
}
[Route("id/{value}")]
public ActionResult Import(decimal? importId)
{
return View();
}
[Route("text/{value}")]
public ActionResult Import(string importWindow)
{
return View();
}
}
One of the ACTION (Import) has different PREFIX such as window and id but whenever I try to access it (such as https://localhost/Explorer/Import/window/helloWorld OR https://localhost/Explorer/Import/id/200) it keeps giving me the following error
The current request for action 'Import' on controller type
'ExplorerController' is ambiguous between the following action
methods: System.Web.Mvc.ActionResult
Import(System.Nullable`1[System.Decimal]) on type
projectname.Controllers.ExplorerController System.Web.Mvc.ActionResult
Import(System.String) on type projectname.Controllers.ExplorerController
I know it is ambiguous but I have a prefix which should make it non-ambiguous.
What am I doing wrong here and how to achieve this outcome if this is not the right way to do it?
Apply the [Route()] attribute for action methods in the controller class:
[RoutePrefix("Explorer")]
public class ExplorerController : Controller
{
// GET: Explorer
public ActionResult Index()
{
return View();
}
// Example: https://localhost/Explorer/Import/id/200
[Route("Import/id/{importId:decimal}")]
public ActionResult Import(decimal? importId)
{
return View();
}
// Example: https://localhost/Explorer/Import/window/helloWorld
[Route("Import/{text}/{importWindow}")]
public ActionResult Import(string importWindow)
{
return View();
}
}
Define only the Default route in the RegisterRoutes() method:
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 }
);
}

MVC going to the wrong view using area in mvc

I have an area name HR. here is the HRAreaRegistration.CS
namespace WebApplication1.Areas.HR
{
public class HRAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "HR";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"HR_default2",
"HR/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"HR_default1",
"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
in RouteConfig.cs
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 },
new[] { "WebApplication1.Controllers" }
);
}
}
I was hoping that since I prioritized the main controller namespace when I go to Home/Index I would hit the view and controller HomeController/Index. Instead I am going to the Home Controller in the HR Area. HR/HomeController/Index. not sure what I am doing wrong.
here is home controller (the one I would like to hit when I go to Home/Index)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
and here is the home controller in the hr area (the one I am hitting when I go to Home/Index even though I shouldn't be)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplication1.Areas.HR.Controllers
{
public class HomeController : Controller
{
// GET: HR/Home
public ActionResult Index()
{
return View();
}
}
}
/***********Editing my question in response to pfx answer********************/
for this application if a certain variable is set then the default page should be in the HR area. specifically HR area Controller OST action Index. so all of the following should take us to that view.
http://nrdephrs01/hrpa
http://nrdephrs01/hrpa/ost
http://nrdephrs01/hrpa/ost/index
http://nrdephrs01/hrpa/hr/ost/
http://nrdephrs01/hrpa/hr/ost/index
now when they get to this default page there is a link that is to take them to Users/Details/1524 so this controller is not in an area. it is just Controller = Users Action = Details.
here are my routes which work until I try to go to the Users/Details/1524 where it can not find the controller.
HRAreaRegistration
namespace Portal.UI.Areas.HR
{
using System.Web.Mvc;
public class HRAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "HR";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"HR_default",
"HR/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
// if the application is Out of State travel there will be an appsetting called OST set to true.
// for OST applications have the main default page be HR/OST/Index
string ost = System.Configuration.ConfigurationManager.AppSettings["OST"];
if (ost == "true")
{
context.MapRoute(
"Details",
"Users/{action}/{id}",
new { controller = "Users", action = "Index", id = UrlParameter.Optional });
context.MapRoute(
"HR_default1",
"{controller}/{action}/{id}",
new { controller = "OST", action = "Index", id = UrlParameter.Optional });
}
}
}
}
and here is RouteConfig.cs
{
using System.Web.Mvc;
using System.Web.Routing;
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 });
}
}
}
From the comments I read that you want http://localhost:50908/HRHome/Index to be handled by the HRHomeControllerin the HR area.
To do so you have to define an explicit route in HRAreaRegistration.cs for HRHome, replacing {controller} with HRHome in the route template.
Having this route with an explicit and unique route template eliminates any conflicts with other routes, including those from the default area.
It is important to register this route from within the AreaRegistration instead of RouteConfig, otherwise the views don't get resolved from the appropriate views folder within the HR area.
context.MapRoute(
name: "HRHome"
url: "HRHome/{action}/{id}",
defaults: new {
controller = "HRHome",
action = "Index",
id = UrlParameter.Optional
},
namespaces: new [] { "WebApplication1.Areas.HR.Controllers" }
);
The full area registration looks like:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "HRHome"
url: "HRHome/{action}/{id}",
defaults: new {
controller = "HRHome",
action = "Index",
id = UrlParameter.Optional
},
namespaces: new [] { "WebApplication1.Areas.HR.Controllers" }
);
context.MapRoute(
name: "HR_default"
url: "HR/{controller}/{action}/{id}",,
defaults: new {
controller = "HRHome",
action = "Index",
id = UrlParameter.Optional
},
namespaces: new [] { "WebApplication1.Areas.HR.Controllers" }
);
}

Unable to reach ASP.NET MVC Web Api endpoint

I am working on an ASP.NET MVC app. I am trying to create a basic API. I created my first Web API controller by right-clicking on Controllers, Add -> Controller... then choosing "Web API 2 Controller - Empty". In the controller code, I have the following:
namespace MyProject.Controllers
{
public class MyApiController : ApiController
{
public IHttpActionResult Get()
{
var results = new[]
{
new { ResultId = 1, ResultName = "Bill" },
new { ResultId = 2, ResultName = "Ted" }
};
return Ok(results);
}
}
}
When I run the app, I enter http://localhost:61549/api/myApi in the browser's address bar. Unfortunately, I get a 404. I'm just trying to create an API endpoint that returns a hard-coded set of JSON objects. I need this to test some client-side JavaScript. What am I doing wrong?
Here are how my routes are registered:
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
RouteConfig.cs
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 }
);
}
Make sure that you have the WebApiConfig registration being called, possibly in the Global.asax Application_Start() method. Something like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
You did not add method name at the end of call. Try this one:
http://localhost:61549/api/myapi/get
Try this approach
namespace MyProject.Controllers
{
public class MyApiController : ApiController
{
public IHttpActionResult Get()
{
var results = new List<ResultModel>
{
new ResultModel() {ResultId = 1, ResultName = "Bill"},
new ResultModel() {ResultId = 2, ResultName = "Ted"}
};
return Ok(results);
}
}
public class ResultModel
{
public int ResultId { get; set; }
public string ResultName { get; set; }
}
}
Api: http://localhost:61549/api/MyApi/get
Hope this helps.

default route parameters in asp.net mvc RouteConfig

I have RouteConfig
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "EmployerDefault",
url: "{lang}/employer",
defaults: new { lang = "ru", controller = "Employer", action = "Index" }
);
}
}
and Controller
public class EmployerController : Controller
{
public ActionResult Index()
{
return View("EmployerMaster");
}
}
When i go to link /employer , i get HTTP 404.0 - Not Found ,
but when i try to get /ru/employer it's OK.
I want that /employer and /ru/employer links refer to one page.
Why it's happens ? How can i fix that ?
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "EmployerDefault",
url: "/employer",
defaults: new { lang = "ru", controller = "Employer", action = "Index" }
routes.MapRoute(
name: "EmployerWithLang",
url: "{lang}/employer",
defaults: new { lang = "ru", controller = "Employer", action = "Index" }
);
}
}

ASP.NET MVC URL Routing with ControllerName/ExampleID

i'm getting this error when i'm navigate browser to url:
localhost:10793/RealEstates/10
this my RouteConfig code:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Main", action = "Index" }
);
routes.MapRoute(
name: "RealEstates",
url: "RealEstates/{action}",
defaults: new { controller = "RealEstates", action = "Index" }
);
routes.MapRoute(
name: "RealEstatesViewAd",
url: "RealEstates/{id}",
defaults: new { controller = "RealEstates", action = "ViewAd", id = UrlParameter.Optional }
);
}
}
my error:
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
when changed code to:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}",
// defaults: new { controller = "Main", action = "Index" }
//);
//routes.MapRoute(
// name: "RealEstates",
// url: "RealEstates/{action}",
// defaults: new { controller = "RealEstates", action = "Index" }
//);
routes.MapRoute(
name: "RealEstatesViewAd",
url: "RealEstates/{id}",
defaults: new { controller = "RealEstates", action = "ViewAd", id = UrlParameter.Optional }
);
}
}
it's work but when i call on other actions in controller
localhost:10793/RealEstates/CreateAd
this error found
The parameters dictionary contains a null entry for parameter 'id' of
non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult ViewAd(Int32)' in
'Youe3lan.Controllers.RealEstatesController'. An optional parameter
must be a reference type, a nullable type, or be declared as an
optional parameter.
Parameter name: parameters
and this my controller:
namespace MvcAppliction1.Controllers
{
public class RealEstatesController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult ViewAd(int id)
{
return View();
}
public ActionResult CreateAd()
{
return View();
}
}
}
You need to change it to:
routes.MapRoute(
name: "RealEstatesViewAd",
url: "RealEstates/{action}/{id}",
defaults: new { controller = "RealEstates", action = "ViewAd", id UrlParameter.Optional }
);}}
Have a look here it might help:
http://msdn.microsoft.com/en-us/library/cc668201(v=vs.100).aspx
UPDATE
Add this to your controller:
public ActionResult ViewAd(Int32 id)
{
return View();
}
You see
localhost:10793/RealEstates/10
is translated to:
localhost:10793/RealEstates/ViewAdd/10
So you need that method in the controller accepting an it parameter.
you've flagged your id in your route as optional:
id = UrlParameter.Optional
but I bet your controller isn't nullable??
public ActionResult ViewAd(Int32 id)
{
}
So you cant post a null into your id even though the route allows it. If you change this to:
public ActionResult ViewAd(Int32? id)
{
}
You won't get the error message:
The parameters dictionary contains a null entry for parameter 'id' of
non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult ViewAd(Int32)' in
'Youe3lan.Controllers.RealEstatesController'. An optional parameter
must be a reference type, a nullable type, or be declared as an
optional parameter. Parameter name: parameters

Resources