I have the following sample data from a MySQL table.
My question is in my MVC 4 project how can I get routing to work so that if a user goes to the URL www.mydomain.com/products/apples/ I want the call to actually be the view of www.mydomain.com/products/index/1, how do I achieve this ?
You could create this one route:
routes.MapRoute("Product", "products/{productName}",
new {controller = "products", action="index"});
This route is saying:
When a request comes in with a URL matching the pattern: "products/{productName}" (e.g. http://www.example.com/products/apple), pass that over to the "index" action in the "ProductsController" to handle and pass the segment of the url indicated by the {productName} placeholder, in to that action as the parameter called "productName".
Then your action would be:
[HttpGet]
public ActionResult Index(string productName) {
// Lookup product from DB
// do stuff
var viewModel = ...;
return View(viewModel);
}
So, when a request comes in for products/apple, "apple" gets passed into the Index action as the productName parameter.
Put below code in you RouteConfig.cs before the default route expression.
foreach (var item in _context.products)
{
routes.MapRoute(
item.Url,
"products/" + item.Url,
new { controller = "products", action = "index", #id = item.ProductId }
);
}
In above _context.products is used to retrieve the products from the DB. You can modify this according your models.
Related
I could use some assistance with this. I have a controller action I've modified to take in a string. When I try to pass the string in the URL its still returning null. All its suppose to do is take in the string, then query based on that string and return the user's name in header tags. Do I need to modify my routes?
Header in View
<div class="nameBlock col-md-push-9">
<h4>Welcome #ViewBag.HeaderName</h4>
</div>
Controller Method
public ActionResult Index(string LanID)
{
var name = db.UserInfoTable
.Where(x => x.Lan_Id == #LanID)
.Select(x => new UserViewModel
{
AppUserName = x.FirstName + " " + x.LastName
}).FirstOrDefault();
ViewBag.HeaderName = name.AppUserName;
return View();
}
Unless you have set up your routing to do something with the LanID parameter, the MVC model binder won't know what to do with it. So you should either change the URL you want to use and tell MVC the name of the parameter by using a query string:
localhost:(portnumber)/DevArea/Dev/Index?LanID={value}
Or add an additional route to your configuration, for example (this is from memory so might need tweaking):
routes.MapRoute(
name: "LanID",
url: "{area}/{controller}/{action}/{LanID}",
defaults: new
{
area = "DevArea",
controller = "Dev",
action = "Index"
}
);
ActionLink is executing properly but not passing id variable.
This is executed first in my main view
<li>#{ Html.RenderAction("ReviewAverage", "Home", Model.TripId); }</li>
which executes this:
[ChildActionOnly]
public ActionResult ReviewAverage(int? id)
{
Trip trip = db.Trips.Find(id);
List<int> values = trip.Reviews.Select(review => review.Rating).ToList();
double average = values.Average();
ViewData["ReviewAverage"] = average;
return PartialView("_ReviewAverage", id);
}
This is the partial view that above method returns and which doesn't for some reason pass the id = Model even though Model variable is definitely set.
The actionLink below is not passing the id to my controller
#model int
<li>#Model</li>
#Html.ActionLink("Reviews (avg: "+ ViewData["ReviewAverage"] +")", "Reviews", "Home", new { id = Model }))
Which should lead to with that id
public ActionResult Reviews(int? id)
{
Trip trip = db.Trips.Find(id);
List<Review> reviews = trip.Reviews;
return View(reviews);
}
When creating a link to a controller action in ASP.NET MVC, using the generic ActionLink method is preferable, because it allows for strongly typed links that are refactoring friendly. Try this:
#Html.ActionLink("Reviews", "Home", new { id = item.Id })
For more information you might have a look at How do I set a click event in C#?. Hope this helps...
The third parameter of the RenderAction overload is the route values. The method expects a dictionary with key and value. Make sure the key matches your action method parameter.
You can pass an annonymous object with id property (which matches your ReviewAverage action method param name.
#{ Html.RenderAction("ReviewAverage", "Home", new { id= Model.TripId} ); }
Now for your action link, you are using the overload incorrectly, The overload you are using expects the last parameter to be an anonymous object need to build the html attributes(ex : css class/ other html attributes).
You can use the correct overload which takes 5 parameters ( 4th one is route values nd 5th one is htmlAttributes)
#Html.ActionLink("Reviews (avg: "+ ViewData["ReviewAverage"] +")",
"Reviews", "Home", new { id = Model },null))
I have a list of products with some title field, e.g.:
ID Title
1 TShirts CK
2 Brand new books
3 Selling whatever I have useless
Ok, I'm calling a Detail method this way:
<a href='#Url.Action("Detail", "Products", new { productId = 3 })'>See detail</a>
[Route("detail/{productId:int}")]
public ViewResult Detail(int productId) {
//...
return View();
}
The generated URL is:
http:example.com/products/detail/3
Well, the idea I want is show an URL like this:
http://example.com/products/detail/3/selling-wathever-i-have-useless
Is there a nice and clean way to do this, based on the given scenario?
I believe this has been termed a URL slug, which will make it 100x easier to search for. I suggest you start: https://stackoverflow.com/a/2921135/507025 for an algorithm to help you slugify your url.
If you have a database with the information, you might want to save the slugified description to it so you can check for duplicates upon the creation of a new item.
Routing will be very similar although you'll be needing to change your routing attribute to:
[Route("detail/{productName:string")]
public ViewResult Detail(string productName)
{
return View();
}
You can then search your DB for the slugified description to return the item searched for OR use the terms given in a search to return multiple results.
There are probably different ways of doing this but now that you know it's called 'slug' you will have an easier time finding info about them.
You can have a route as below and when you define Url.Action you can pass product title to some kind of method which convert the given text to URL friendly text.
Example
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{productId}/{title}",
defaults: new { controller = "Home", action = "Index", productId = UrlParameter.Optional, title = UrlParameter.Optional }
);
<a href='#Url.Action("Index", "Home", new { productId = product.ID, title = ToFriendlyUrl(product.Title) })'>See detail</a>
public ViewResult Detail(int productId, string title)
{
// ...
return View();
}
Thanks!
I've been working on a large MVC application over the past month or so, but this is the first time I've ever needed to define a custom route handler, and I'm running into some problems. Basically I have two parameters to pass. The first one is required and the second one is optional.
I'm following this answer here.
Here is my custom route:
routes.MapRoute(
"MyRoute",
"{controller}/{action}/{param1}/{param2}",
new {
controller = "MyController",
action = "MyAction",
param1 = "",
param2 = "" // I have also tried "UrlParameter.Optional" here.
}
);
And my action method signature:
public ActionResult MyAction(string param1, string param2)
If I try the URL http://[myserver]/MyController/MyAction/Test1/Test2 then it works like I expect it to, with param1 = "Test1" and param2 = "Test2"
If I try the URL http://[myserver]/MyController/MyAction/Test1 then both parameters are null.
Hopefully somebody can tell me what I'm doing wrong here, because I'm lost.
I assume that you created new route and left the default one that is very similar to yours. You should be aware that collection of routes is traversed to find first matching route. So if you have left the default one:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
above your route then it will match request to http://[myserver]/My/MyAction/Test1 and call MyController.MyAction and set "Text1" to parameter named id. Which will fail because this action is not declaring one named id.
What you need to do is to move your route as first in routes list and make it more specific then it is now:
routes.MapRoute(
"Route",
"My/{action}/{param1}/{param2}",
new
{
controller = "My",
action = "MyAction",
param1 = "",
param2 = ""
});
This will force all traffic routed trough My to match this route.
hi you create your rout like this i think this will hep you
routes.MapRoute(
"Regis", // Route nameRegister
"Artical/{id}", // URL with parameters
new { controller = "Artical", action = "Show", id = UrlParameter.Optional } // Parameter defaults
);
Try this
routes.MapRoute("MyRoute",
"myRoute/{param1 }/{param2 }",
new { controller = "MyController", action = "MyAction", param2 = UrlParameter.Optional },
new { param2 = #"\w+" });
you can specify one parameter as optional by using "UrlParameter.Optional" and specified second one with DataType means if you pass integer value then DataType (#"\d+") and for string i have mention above.
NOTE: Sequence of parameter is very important Optional parameter must pass at last and register your new route Before Default Route In Gloab.asax.
then you action link like
Test
OR with one parameter
Test
In you Controller
public ActionResult MyAction(string param2,string param1)
{
return View()
}
I can't seem to retrieve an ID I'm sending in a html.ActionLink in my controller, here is what I'm trying to do
<li>
<%= Html.ActionLink("Modify Villa", "Modify", "Villa", new { #id = "1" })%></li>
public ActionResult Modify(string ID)
{
ViewData["Title"] =ID;
return View();
}
That's what a tutorial I followed recommended, but it's not working, it's also putting ?Length=5 at the end of the URL!
Here is the route I'm using, it's default
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
Doesn't look like you are using the correct overload of ActionLink. Try this:-
<%=Html.ActionLink("Modify Villa", "Modify", new {id = "1"})%>
This assumes your view is under the /Views/Villa folder. If not then I suspect you need:-
<%=Html.ActionLink("Modify Villa", "Modify", "Villa", new {id = "1"}, null)%>
In MVC 4 you can link from one view to another controller passing the Id or Primary Key via
#Html.ActionLink("Select", "Create", "StudentApplication", new { id=item.PersonId }, null)
Don't put the # before the id
new { id = "1" }
The framework "translate" it in ?Lenght when there is a mismatch in the parameter/route
On MVC 5 is quite similar
#Html.ActionLink("LinkText", "ActionName", new { id = "id" })
The ID will work with # sign in front also, but we have to add one parameter after that. that is null
look like:
#Html.ActionLink("Label Name", "Name_Of_Page_To_Redirect", "Controller", new {#id="Id_Value"}, null)
If the target action requires a parameter, you can use an anonymous object to pass parameter values:
#Html.ActionLink(“View Movies”, “Index”, “Movies”, new{id=1},null)
Where:
-View Movies-->String LinkText
-Index--> string ActionName
-Movies-->string ControllerName
-new{id=1}-->(object) Is the parameter values that you want to pass
-Null-->object htmlAttributes
*For Example:
This should generate a link like the following:
/movies/index/1