asp.net mvc 4 custom urls for action method - asp.net

I am creating a asp.net mvc 4 application
public class AspNetController : Controller
{
//
// GET: /AspNet/
public ActionResult Index()
{
return View();
}
public ActionResult Introduction()
{
return View();
}
}
as Shown Above There is AspNet Controller and Introduction Action Method
Default Url for Introduction Action Method is
localhost:55134/aspnet/introduction
But I Want Url Like
localhost:55134/aspnet/introduction-To-AspNet
Same for
/localhost:55134/aspnet/NetFrameWork To
/localhost:55134/aspnet/What-is-.Net-Framework
How to do that

You should be able to use the ActionName attribute to decorate your routes.
[ActionName("Introduction-To-AspNet")]
public ActionResult Introduction()
{
return View();
}
You really want to use AttributeRouting, either via a 3rd party package or natively if you can.

Technically this concept comes under Routing in ASP.NET MVC.
For this you need to do an entry for route in App_Start->RouteConfig.cs file under RegisterRoutes(RouteCollection routes)
For Example:
routes.MapRoute(
"customRouteName",
"aspnet/introduction-To-AspNet",
new { controller = "AspNet", action = "Introduction" });
here aspnet/introduction-To-AspNet will append after your base url i.e. localhost:55134/

The quick and dirty answer is to add a route to your ~/AppStart/RouteConfig.cs file and it will be taken care of:
routes.MapRoute(
name: "CustomRoute",
url: "Aspnet/Introduction-To-AspNet",
defaults: new { controller = "Home", action = "AspNet", id = UrlParameter.Optional }
);
However, I'm assuming this is for some type of blog? I would reccomend that you have an action method called view, and then use your name as a parameter for the article. That way, you don't have to go in and edit the code every time you add a new article or other content:
public class ArticlesController : Controller
{
public ActionResult ViewArticle(string? title)
{
ViewBag.Article = title;
return View();
}
}
that way, your URL would be www.yoursite.com/Articles/ViewArticle/Introduction-To-AspNet. In general, you don't want to add tons of specific routes to your route config if you can avoid it. That being said, if this is a legacy system, the route table may be the only way.
EDIT
Ok, so what you can do is pass the string into the ViewBag and use a case statement to determine which partial view to show (I think this just might be your ideal solution):
<!--cshtml view-->
#switch(ViewBag.Article)
{
case 'Introduction-To-AspNet':
#Html.Partial('pathToPartialView.cshtml')
break;
case 'Some-Other-Article'
#Html.Partial('pathToAnotherPartialView.cshtml')
break;
...
...
default:
#Html.Partial('invalidArticleName.cshtml')
break;
}
The controller will pass the article name through the ViewBagand then you can use the case statement to figure out which article to render... and of course, the real secret sauce you've been looking for: #Html.Partial('URL') - this will take your partial and render it right were you put that in the page. You can also pass objects to that just as an FYI.
In addition, make sure that you have a default action on the switch statement that will show some sort of 404 page that indicates that the name in the URL was invalid. You ALWAYS want to have this anytime you're taking user input from the URL because people monkey with URLs all the time (and more innocently, copy+paste them wrong/incompletely all the time)

Related

Fill a form with ASP.NET MVC Querystring

I want to fill a form with Id and i have made the url in this way
local-host:1613/Patient/Index/1
Where as 1 is the Id. And i want to fill my form with the data of patient with Id 1.
But this below function is not being called in Controller
public ActionResult Index(int id)
{
Patient p = new CEntities().Patients.Find(id);
return View(p);
}
instead, i am getting into
public ActionResult Index()
{
return View();
}
I am newbie in ASP.NET MVC, i have no idea in filling a form with any other way, i found a way but it shows my whole object in query string which is insecure. And this above solution is not working.
Please suggest me good solution.
As far as I know you cannot truly overload action methods in ASP.NET-MVC so there can be only one Index action method(without any additional annotations). Of course you can define few methods with the same name but then you might want to add [HttpPost](or other HTTP method) annotation above the action method to use it for instance after submitting a form.
Making parameter optional might be helpful:
public ActionResult Index(int? id){
if(id.HasValue()){
Patient p = new CEntities().Patients.Find(id);
return View(p);
}
return View();
}
Please take a look: Can you overload controller methods in ASP.NET MVC?
Another advice: try to use scaffolding and see how template does it for you:
1.Right click on a controller folder
2.Add->New Controller
3.Controller with Entity Framework read/write actions(as far as I remember 3rd from the top)
4.Select model class.
5.Select db context(class which maintains connection with database).
6.Ok.
It will generate controller with views, have fun.
local-host:1613/Patient/Index/1
This path should be hitting your action method of:
public ActionResult Index(int id)
Please check your RouteConfig.cs file and make sure you have the default route set up correctly:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Try commenting out your other Index action method "//public ActionResult Index()", and see what happens when trying to go to local-host:1613/Patient/Index/1

MVC 3 wildcard route ie www.mydomain.com/username

I would like to create a simple route which will allow me to have ONLY one item listed after the base URL (other than when it's a controller), and for that item to be passed into a controller as a parameter. for example:
www.mydomain.com/user1
www.mydomain.com/user2
www.mydomain.com/user3
www.mydomain.com/user3
where user1, user2 etc are usernames and are being passed dynamically, ie i don't want to have to create a controller for each username.
naturally i would want to make sure if something like this is possible that it wont cause conflicts with other genuine controller names, thus i guess the other controllers would have to have rules created specifically for them and listed above the wildcard route
i'm not sure how to do this as i guess the first item after the slash is usually a controller.
any ideas how to tackle this?
the examples i provided may seem ambiguous, when i put www.mydomain.com/user1 etc it represents that it could be anything (ie a username),for example, www.mydomain.com/jsmith, www.mydomain.com/djohnson, www.mydomain.com/sblake, www.mydomain.com/fheeley
the idea is that a users profile can be looked up simply by entering the domain name then a fwd slash and the username.
ASP.Net MVC routes are process from the top down, and as soon as a match is found it won't look any further for a match. So put your most specific routes first, and your wildcard route last. If none of the specific routes match, control will be passed to the wildcard route.
Use a route definition such as
routes.MapRoute("{username}", new { controller = "User", action = "View"});
in your global.asax.cs file but put it last in your list of route definitions.
MVC processes your route mappings from top to bottom, so put your most general route mappings at the top, and your more specific ones at the bottom.
After you do this you will need the corresponding controller/action so create a new Controller named "UsersController" with an action named "View", like as follows:
using System.Web.Mvc;
namespace Routes.Controllers
{
public class UsersController : Controller
{
//
// GET: /{username}
public ActionResult List(string username)
{
// Get User from database/repository and pass to view
var user = ...;
return View(user);
}
}
}
You have to do following thing.
Create one controller or Action for Handle above scenario. For example controller="Home" and Action="GetUser"
public ActionResult GetUser(string username){
// do your work
}
In Global.asax ( Top route)
// Look at point 3 for UserNameConstraint
route.MapRoute("UserRoute" , "{username}" , new { controller="Home" , action="GetUser" } , new { username = new UserNameConstraint() });
// Put your default route after above here
Now for Create Route constraint.
Hope this help you.
public class UserNameConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
List<string> userName = GetUserName from DB
userName.Contain(values[parameterName].ToString());
}
}
Create a route like as follows,
routes.MapRoute(
"DefaultWithUser", // Route name
"{user}/{controller}/{action}/{id}", // URL with parameters
new { user=UrlParameter.Optional, controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

Infinite URL Parameters for ASP.NET MVC Route

I need an implementation where I can get infinite parameters on my ASP.NET Controller. It will be better if I give you an example :
Let's assume that I will have following urls :
example.com/tag/poo/bar/poobar
example.com/tag/poo/bar/poobar/poo2/poo4
example.com/tag/poo/bar/poobar/poo89
As you can see, it will get infinite number of tags after example.com/tag/ and slash will be a delimiter here.
On the controller I would like to do this :
foreach(string item in paramaters) {
//this is one of the url paramaters
string poo = item;
}
Is there any known way to achieve this? How can I get reach the values from controller? With Dictionary<string, string> or List<string>?
NOTE :
The question is not well explained IMO but I tried my best to fit it.
in. Feel free to tweak it
Like this:
routes.MapRoute("Name", "tag/{*tags}", new { controller = ..., action = ... });
ActionResult MyAction(string tags) {
foreach(string tag in tags.Split("/")) {
...
}
}
The catch all will give you the raw string. If you want a more elegant way to handle the data, you could always use a custom route handler.
public class AllPathRouteHandler : MvcRouteHandler
{
private readonly string key;
public AllPathRouteHandler(string key)
{
this.key = key;
}
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var allPaths = requestContext.RouteData.Values[key] as string;
if (!string.IsNullOrEmpty(allPaths))
{
requestContext.RouteData.Values[key] = allPaths.Split('/');
}
return base.GetHttpHandler(requestContext);
}
}
Register the route handler.
routes.Add(new Route("tag/{*tags}",
new RouteValueDictionary(
new
{
controller = "Tag",
action = "Index",
}),
new AllPathRouteHandler("tags")));
Get the tags as a array in the controller.
public ActionResult Index(string[] tags)
{
// do something with tags
return View();
}
That's called catch-all:
tag/{*tags}
Just in case anyone is coming to this with MVC in .NET 4.0, you need to be careful where you define your routes. I was happily going to global.asax and adding routes as suggested in these answers (and in other tutorials) and getting nowhere. My routes all just defaulted to {controller}/{action}/{id}. Adding further segments to the URL gave me a 404 error. Then I discovered the RouteConfig.cs file in the App_Start folder. It turns out this file is called by global.asax in the Application_Start() method. So, in .NET 4.0, make sure you add your custom routes there. This article covers it beautifully.
in asp .net core you can use * in routing
for example
[HTTPGet({*id})]
this code can multi parameter or when using send string with slash use them to get all parameters

Custom route with more than one parameter in url (customer, extra info)

I have a multi tenant system and I need to allow administrators to edit the information of other customers.
I believe the correct way to do this is to append the customer ID to each request, and update my routes accordingly.
How do I make ASP.NET accept and use something like this in the controller (order doesn't mean much to me):
mysite.com/files/delete/{file}/{customerID}
and how would I pass and consume that in my controller? The ASP.NET tutorials skip this... (or I don't know where to search)
Define a route:
//mysite.com/files/delete/{file}/{customerID}
routes.MapRoute(
"Files", // Route name
"files/delete/{file}/{customerID}", // URL with parameters
new { controller = "File", action = "Delete" } // Parameter defaults
);
Create a Controller:
public class FileController : Controller
{
public ActionResult Delete(string file, string customerID)
{
//do something
return View();
}
}
I presume that {file} is a filename that should be deleted.

ASP.NET MVC route returning 404 without action

I am working on a very simple application, using MVC2 Preview 1.
I have a controller named ContentController. My problem is that /Content/Index works correctly, but /Content/ returns a 404. I am running the application on the Studio Development Server.
Tested with RouteDebugger but /Content/ returns a 404, and does not display any debugging information.
I have not changed the routing code:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
This is my controller:
public class ContentController : Controller
{
IRepository _repo = new SimpleRepository("db", SimpleRepositoryOptions.RunMigrations);
public ActionResult Index()
{
var content = _repo.GetPaged<Content>(0, 20);
return View(content);
}
It's a shot in the dark, but do you have a directory named /Content/ as well?
/Content is a controller, which is basically just a collection of actions. ASP.NET MVC needs to know WHICH action you want to run, so by leaving out the action asp.net mvc doesn't know what action to return and gives a 404.
You can tell it a default either by adding a route:
eg:
routes.MapRoute("ContentDefault", "Content", new {controller = "Content", action = "Index"});
The attributes are defined as follows:
'ContentDefault`: Name of the Route (must be unique in your routing table)
Content: The URL segment (try changing this to 'Content/Much/Longer/URL' and then go to http://localhost/Content/Much/Longer/URL to see how this works)
new {controller=.., action=...}: which controller/action combo to run for this route.
You could also override HandleUnknownAction in your controller:
protected override void HandleUnknownAction(string actionName)
{
return RedirectToAction("index");
}
Oh and incidentally, an extra piece of advice about routing.... if you add something to the route in braces { } these will be passed to the action as an attribute.
e.g. /Content/Much/Longer/Url/{page}
so the URL http://localhost/Content/Much/Longer/Url/999
will pass the 999 into your action, as the page attribute
public ActionResult Index(int Page) { }
I love MVC - never going back to WebForms - this is how web development should be!

Resources