How to define default action parameters in ASP.NET MVC 4 - asp.net-mvc-4

I am following Pluralsight videos to learn MVC4.
While learning about default values for action parameters I have defined the following setting inside RouteConfig.cs
routes.MapRoute(
name: "cuisine",
url: "cuisine/{name}",
defaults: new { controller="cuisine", action="search", name=""});
I have created CuisineController with Search() as the action method like below:
public ActionResult Search(string name="India")
{
var message = Server.HtmlEncode(name);
return Content(message);
}
As per the video I have seen, if nothing is passed in the URL then India should come as output.
But, I am getting empty string.
Where I am doing wrong?

You have to use UrlParameter.Optional
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{name}", // URL with parameters
new { controller = "Home", action = "Search", name = UrlParameter.Optional } // Parameter defaults
);
public ActionResult Search(string name = "India")
{
var message = Server.HtmlEncode(name);
return Content(message);
}
This displayed "India" perfectly in page.

Related

Area routing breaks in MVC6

In previous versions of ASP.NET, and using MVC 5, I could set up a route like this in my AreaRegistraion:
context.MapRoute(
"pfrecent",
"Forums/Recent/{page}",
new { controller = ForumController.Name, action = "Recent", page = 1 },
new[] { "PopForums.Controllers" });
This would route /Forums/Recent to the forum controller and its recent action. However, I can't figure out how to make it work in ASP.Net 5/MVC 6. I've added [Area("Forums")] to the controller class, and used this route from the Startup class:
routes.MapRoute(
"pfrecent",
"Forums/Recent/{page}",
new { controller = ForumController.Name, action = "Recent", page = 1 });
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
However, it resolves to /Forums/Forum/Recent?page=1. The intention is to continue using /Forums/Recent.
We are using this for enabling areas in MVC 6:
// Configure MVC routing
app.UseMvc(routes =>
{
// Areas support
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
// Default routing
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
The first route is for areas, second is for main content.
On Startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "Business",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
})
on Controller
[Area("Business")]
public class DemoController : Controller
{
public IActionResult Index()
{
return View();
}
}
Place this in your Startup.cs file at the TOP of the routes list:
routes.MapRoute(
name: "forumsAreaRoute",
template: "Forums/{action}/{page?}",
defaults: new {area = "Forums", controller = "Forum", action = "Recent", page = 1});
Your Forum controller should look like this:
[Area("Forums")]
public class ForumController : Controller
{
// GET: /<controller>/
public IActionResult Recent(int? page)
{
// Do action stuff here
}
}
This solution will satisfy a url of http://somedomain.com/Forums/Recent/1 and return the first page.
I hate answering my own questions, but after getting back to this, and looking at source and experimenting, I found that you have to specify the area in the route mapping, as well as the HtmlHelpers (I'm assuming this will be true for tag helpers as well, but I haven't gone that far yet in conversion.) So the route mapping has to look like this:
routes.MapRoute(
"pfrecent",
"Forums/Recent/{page?}",
new { controller = ForumController.Name, action = "Recent", page = 1, Area = "Forums" }
);
The important part is the Area property in the route value object. The HtmlHelper has to look like this, also naming the Area:
#Html.ActionLink(PopForums.Resources.Recent, "Recent", ForumController.Name, new { page = 1, Area = "Forums" }, null)
It causes the URL for the recent page to be /Forums/Recent as expected. As best I can tell, setting routes in a derived AreaRegistration class in MVC5 set the area value on the routes for you. Having [Area("Forums")] on your controller class (which I already had) seems to assume the previous role of area registration.

Add Custom Route name with custom action name in WebApi

I have my WebApiController with name AdminDashBoard.
public class AdminDashBoardController : ApiController
{
[System.Web.Http.AcceptVerbs("GET")]
public HttpResponseMessage GetCaseHistory(string CaseRefId, string token)
{
**Implementation**
}
}
I am able to access API using
Localhost/api/AdminDashBoard/GetCaseHistory?CaseRefId=CTcs004&token=eygk
But i want to access this by custom name such as
Localhost/api/Cases/GetCaseHistory?CaseRefId=CTcs004&token=eygk
I have defined customroutes in my WebApiConfig but it is not working.
config.Routes.MapHttpRoute("CaseHistory", "api/cases/{action}/{CaseRefId}/{token}", defaults: new { controller = "AdminDashBoard", action = "GetCaseHistory", CaseRefId = RouteParameter.Optional, token = RouteParameter.Optional });
the routing you configured will resolve to:
controller => AdminDashBoard
action => GetCaseHistory
But please note that since you've placed /{action} in rout template string, it will affect detection of routing to expect an "action" specified in request URL.
could you try this:
config.Routes.MapHttpRoute("CaseHistory",
"api/Cases/GetCaseHistory",
defaults:
new { controller = "AdminDashBoard",
action = "GetCaseHistory" });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
remember to place your route before default route as default route will capture the request before the customized one.
In addition, you don't need to define parameters "CaseRefId" and "token" in query string into routing, it should be resolved if you have defined correct type in controller method.
Hope this helps.

Custom route MVC4 with constraints

I have an MVC 4 application that i want to create custom route to respective controllers.
The goal is simply to not show the action name in the url, rather only show controller name and parameters.
routes.MapRoute(
"Account", // Route name
"Account/{param}", // URL with parameters
new { controller = "Account", action = "Account", param = UrlParameter.Optional }, // Parameter defaults
new { controller = #"^(Account)$" } //Parameter constraints
);
routes.MapRoute(
"Login", // Route name
"Login/{returnurl}", // URL with parameters
new { controller = "Login", action = "Login", returnurl = UrlParameter.Optional }, // Parameter defaults
new { controller = #"^(Login)$" } //Parameter constraints
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
At the moment i'm using this route above which work fine until i call another action that is not specified in the default parameter/url of each root.
E.g the route to Login/Login or Login/Login?somevalue works as expected to simply not show the action in the url Logn or Login/somevalue. But as soon another action in the same controller is requested the route resolves to Login/Login/Logout for instance. Why is this occurring when i have set the route to match all requests to Login controller?
All actions in the controller have the returnurl parameter
An explanation or clarification on this matter would be greatly appreciated if some could take time and view my routes.
Any help or thoughts would be nice.
Thanks in advance.

Routing Facebook AppRequests in ASP.Net MVC 4

My mobile web site allows users to send an AppRequest to their Facebook friends. This is working.
When the friend accepts the AppRequest, Facebook sends the friend to my web site. This too is working.
My web site is an ASP.Net MVC 4 application. I am trying to get my routes to recognize the incoming AppRequest acceptance but I can't figure out how to do it.
Facebook is sending the friends to my site using this URL:
http://www.example.com/?ref=notif&code=abcdefg&fb_source=notification
This keeps getting routed to Home/Index despite my attempts to map the route to a custom controller and action. Here is what I have done so far that has failed to work:
Registered Routes:
routes.MapRoute(
name: "FacebookAppRequest",
url: "{ref}/{code}/{fb_source}", //This should match the URL above
defaults: new { controller = "Facebook", action ="FBAppRequestHandler"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Controller:
public class FacebookController : Controller
{
public FacebookController() {}
public ActionResult FBAppRequestHandler(
[Bind(Prefix = "ref")] string fbReferal,
[Bind(Prefix = "code")] string fbCode,
[Bind(Prefix = "fb_source")] string fbSource)
{
//Do some stuff with fbReferal, fbCode and fbSource
return View();
}
The ref the code and the fb_source are passed as query string parameters. They are not part of the route. So you cannot possibly expect that {ref}/{code}/{fb_source} would match your custom route. That would have been the case if the request looked like that:
http://www.example.com/notif/abcdefg/notification
Since the actual route looks like this (forget about query string parameters - they are not used for routing):
http://www.example.com/
all that you have here basically is the following url /. So the best you could hope here is to modify your default route so that it routes to the desired controller:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Facebook", action = "FBAppRequestHandler", id = UrlParameter.Optional }
);
Now get rid of the first route - it's not necessary.

ASP.NET MVC URL Routing with parameters in the middle

I have a controller called Quote, with an Index method that requires a requestId parameter. The URL appears as such
/Quote/{requestId}.
Additionally, I have a method called ApplicantInfo which is specific to the quote and routes as such
/Quote/{requestId}/ApplicantInfo.
But when I use the Url.Action helper like so
#Url.Action("Index","Quote",new { requestId = {requestId}})
It gives me a url of
/Quote/ApplicantInfo?requestId={requestId}
which does not route correctly.
Obviously, I can manually create the URL string, but before I throw in the towel I wanted to know if I was missing something, for instance an override to the Url.Action method that will output the correct Url.
TIA
ROUTES
routes.MapRoute(
"QuoteInfo",
"Quote/{requestid}",
new { controller = "Quote", action="Index" });
routes.MapRoute(
"QuoteApplicant",
"Quote/{requestid}/ApplicantInfo",
new { controller = "Quote", action = "ApplicantInfo" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action="Index", id = UrlParameter.Optional });
I was able to get do something similar to this like this
Route
Define a route in Global.asax.cs or whereeve you override your routes
routes.MapRoute(
"Organization_default",
"{controller}/{requestId}/{action}",
new {
controller = "home",
action = "index",
requestId = "default",
id = UrlParameter.Optional
}, null);
Controller
public ActionResult Question(string requestId)
{
ViewData["value"] = requestId;
return View();
}
View
#{
ViewBag.Title = "Index";
var value = ViewData["value"];
}
<h2>Stackoverflow #value</h2>
#Html.ActionLink("Click Here",
"question", "StackOverflow", new { requestId ="Link" }, new{ #id="link"})
Screenshot
screenshot of how the links appear with this route, I defined the
Catch
You CANNOT have another route as {controller}/{action}/{key} defined before your custom this route. If you do the other route override your custom route.
If you need both the routes to co-exist then you would have to define a separate Area and define your custom route overriding RegisterArea
public override void RegisterArea(AreaRegistrationContext context)
{
//..custom route definition
}