I was looking for a way to load different data from the database based on an ID or name in the URL.
For example:
This is the link to the view:
http://localhost:50830/CreateSale/Order
Now I want something like this:
http://localhost:50830/CreateSale/Order/5
OR
http://localhost:50830/CreateSale/Order/Cookies
And then based on the ID (5) or the name (Cookies), the controller CreateSale will load the data that is linked to the ID/name in the Order view. This data will be different for every ID/name.
EDIT
So basically what I want is a way to create a URL like the one I showed. So when I type the link into the browser, depending on the the last part (5 or Cookie), it should show the desired data on the page.
For example:
If the link is:
http://localhost:50830/CreateSale/Order/Cookies
Then I want to see data about ordering cookies on the page.
When the link is:
http://localhost:50830/CreateSale/Order/Toys
Then I want to see data about ordering toys on the page.
Is there any way to do this in asp.net mvc4?
Thanks!
This should work out of the box with the default routing. On the controller method read the Id and pass it to your method that reads from the database, then pass the results back to the view.
public ActionResult Order(string id)
{
var data = DbLoader.Execute(id);
return View(data);
}
On your view, read the data you passed to it. e,g in Index.cshtml.
#foreach (var dataItem in Model)
{
//Display something
}
This assumes you do not have a custom route for "CreateSale/Orders" and is using the default route of :
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
If you do have a custom route for "/CreateSale/Order" ensure the url ends with "/{id}" like the default route.
EDIT
To generate urls use the Url.Action method either in your view or controller. E.g
#Url.Action("Order", "CreateSale", new RouteValueDictionary { { "id","5" } }, Request.Url.Scheme, Request.Url.Host) //generates http://localhost:50830/CreateSale/Order/5
#Url.Action("Order", "CreateSale", new RouteValueDictionary { { "id","Cookies" } }, Request.Url.Scheme, Request.Url.Host) //generates http://localhost:50830/CreateSale/Order/Cookies
#Url.Action("Order", "CreateSale", new RouteValueDictionary { { "id","Toys" } }, Request.Url.Scheme, Request.Url.Host) //generates http://localhost/CreateSale/Order/Toys
Related
I guess I don't completely understand how urls work with C# projects, in the sense that I don't know how to specify a url to go through the controller and not just return a aspx page.
Say I am trying to get to my project's Index page through a Controller named "ScholarshipController.cs". I would think to hit the Index method/action in this controller, my url would be as follows (my app's name is "TuitionAssistance" fyi):
http://localhost/TuitionAssistance/Scholarship/Index
However, running this url just returns the aspx page named "Index.aspx" located in the "Scholarship" view file without hitting the Controller. Why is this happening, and how do I get it to go through the controller so the Index page, when loaded, will have the appropriate information loaded onto it?
Sorry if this is a dumb question. Any insight would be appreciated. Thanks!
Route.config:
using System.Web.Mvc;
using System.Web.Routing;
namespace ScholarshipTuitionAssistance
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
/* Scholarship */
/* Scholarship */
//routes.MapRoute("TuitionAssistance",
// "tuition/{name}",
// new { controller = "TuitionAssistance", action = "Index", name = "" });
routes.MapRoute(
name: "TuitionAssistance",
url: "{controller}/{action}/{employee_number}",
defaults: new { controller = "Home", action = "TuitionAssistance", employee_number = UrlParameter.Optional }
);
routes.MapRoute(
name: "Scholarship",
url: "{controller}/{action}/{employee_number}",
defaults: new { controller = "Home", action = "Scholarship", employee_number = UrlParameter.Optional }
);
routes.MapRoute(
name: "Details",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Scholarship", action = "Details", id = UrlParameter.Optional }
);
}
}
}
Your route (URL) cannot match anything that actually exists on the filesystem. In your example here, you apparently have a file, [document root]\Scholarship\Index.aspx. As a result, a request for Scholarship/Index will return that file, instead of invoking the ASP.NET MVC machinery to load a controller action.
In MVC ASP.NET, think of those types of links as a way to call your methods in your controller. When that link is accessed, your controller does a bunch of junk and then returns an ActionResult (or other things). This ActionResult, for the sake of this explanation, is the markup that is written in the corresponding view file. Controller - >index() will return the view called index under views - > controller. If you want to pass information to your view, you will pass a model that has all of your information in it to the view from your index controller (return View(MyFancyModel)). The view will have a razor line at the top such as: #model The.Namespace.Wherever.my.model.is
The scaffolded controllers and views in Visual Studio for the index page specifically, only pass a list of the items in the corresponding database.
I have a controller and a view which returns book information when I pass the ID, e.g.:
/Content/Index?id=1
Now I want to make this as a friendly URL to end user. For eg:
Books/BookName (Name of the book the Id 1 is mapped to)
So I added a route values in global.asax as :
route.maprRoute(name:"custom", url:"Books/{bookname}",
defaults: new {controller = "bookMap", action ="index"}
in "BookMap" controller I get the bookname and convert that to the ID (which is 1)
and do a redirectionToAction to Content/Index by passing the ID as a parameter.
This works fine. But the problem is I want to keep the friendly name after redirecting to the view. Now it changes to Content/Index?id=1. But I want to keep the friendly URL which is Books/BookName. How do I achieve this pls.
You can use HttpContext.RewritePath(url) to do a redirect "internally" which keeps the external URL. Use this in place of the RedirectToAction. Note however that it's not properly supported by the MVC framework at this time so it will be a little "hacky" to implement.
You should change your route for this:
routes.MapRoute(
"Books",
"book/{bookname}/{bookid}",
new { controller = "book", action = "Index", bookname = UrlParameter.Optional },
new { id = #"\d+" }
);
I have an ASP.NET MVC routing question. First, let me explain my areas setup. It's quite simple.
Areas
|
+--Foo
|
+--Controllers
|
+--BarController.cs
I have a folder in my areas called "Foo" and controller called "BarController.cs" The Bar controller has several methods named "DoStuff1()", "DoStuff2()", etc.
My website uses the following URLs:
/foo/bar/15
/foo/bar/dostuff1
/foo/bar/dostuff2
The first URL requires an id and uses the default Index() method in the Bar controller to populate the webpage with a view and model.
In the second and third URLs, I'm using them for jQuery ajax calls.
Here is the code from my area registrion
context.MapRoute(null, "Foo/Bar/DoStuff1", new
{
action = "DoStuff1",
controller = "Bar"
});
context.MapRoute(null, "Foo/Bar/DoStuff2", new
{
action = "DoStuff2",
controller = "Bar"
});
context.MapRoute(null, "Foo/Bar/{id}", new
{
action = "Index",
controller = "Bar"
});
My problem is that for each new controller method I create, I have to add another route mapping in the area registrion file. For example, if I add the method DoStuff3(), I'll need to add this to the area registration:
context.MapRoute(null, "Foo/Bar/DoStuff3", new
{
action = "DoStuff3",
controller = "Bar"
});
How can I create a generic route mapping to handle the URLs I mentioned above that doesn't require new additions to the area registration file for new controller methods?
You can pull out the controller action.
Write the URL like this:
"Foo/Bar/{action}"
Additionally, you can pull out the controller as well, and write
"Foo/{controller}/{action}"
In this case, action = "Index" provides a default value of "Index" if no action parameter is provided.
In this case, you need to disambiguate between "Foo/Bar/{action}" and "Foo/Bar/{id}". Since matching is done in order, you'll want to put the id route first, and add a numeric constraint to the id parameter. This allows valid numeric ids to match it, and action names to skip down to the next route. Your two routes would look like this:
context.MapRoute(null, "Foo/Bar/{id}", new
{
action = "Index",
controller = "Bar"
},
new { id = #"\d+" });
context.MapRoute(null, "Foo/Bar/{action}", new
{
action = "Index", //optional default parameter, makes the route fall back to Index if no action is provided
controller = "Bar"
});
The default routing that comes with MVC templates are good for most of the needed route configurations.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I know I can change the routing in the RouteConfig in my MVC application:
routes.MapRoute(name: "epage", url: "view/SpecificURL", defaults: new {
controller = "ePage",
action = "Index"
})
but I am wondering how to redirect for values comming from a db. There is one row in my db that has titles . So for each title comming from the db I want to redirect to a specific url
ex.
the title in db may be "pink" I want www.mydomain.com/pink to be rerouted to a specific url . The URL that I want it redirected to is also in the db. I looked at lots of questions on this and can not seem to find any that dynamically change the routing of urls
You can setup a route like this:
routes.MapRoute(name: "Default",
url: "{id}",
defaults: new { controller = "Home", action = "Index" });
Then in your controller (the HomeController in my case):
public ActionResult Index(string id)
{
ContentResult cr = new ContentResult();
// Do a DB lookup here to get the data you need from the database to generate the appropriate content.
cr.Content = id;
return cr;
}
This example simply returns the string that was sent. So now if I browse to http://localhost/mysite/pink I would get "pink" back as my result. You could easily use this method to then do a lookup to your custom database to determine the correct content to return.
If your existing routes don't let you take this route :), then you can always do a SQL query in the RegisterRoutes method and populate the route table from that.
I have website that shows user submitted content in 30+ languages in front page,I am currently using paths like:
http://www.example.com?lang=en
or if it's not first page
http://www.example.com?lang=en&page=2
But that really isn't user or seo friendly.
Is there a way in mvc to route these values to something like
http://www.example.com/en
and
http://www.example.com/en/2
without adding new action in-between like in this case lang:
http://www.example.com/lang/en/2
Update. Here is what I came up from Alexeis answer, in case anybody will need same thing:
In case of just language:
routes.MapRoute("MyLang", "{lang}", new { controller = "Home", action = "Index" },new { lang = #"\D{2}"});
In case you need language and optionally page:
routes.MapRoute("MyLang", "{lang}/{page}", new { controller = "Home", action = "Index", page = UrlParameter.Optional }, new { lang = #"\D{2}", page = #"\d+"});
It should not catch any other paths unless you have Actions with only 2 letters.
You don't need "lang/" for the route to match culture. Simple "{lang}" will do as long as you order routes in a way so other routes are matched correctly. You may also consider constraints on routing parameters to limit number of conflicts.
routes.MapRoute("MyLang", "{lang}",
new { controller = "Home", action = "Home", }
class HomeController{
public ActionResult Home(string lang)
{
return View();
}
}
u can add a new route like this
routes.MapRoute("MyLang", "{action}/{page}",
new { controller = "ControllerName",page=0 }
this way the lang name will automatically be mapped to the action and page will be passed as a parameter provided u have action signature as
public ActionResult English(int page)
obsly the return type and action name can be changed