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"
}
);
Related
I've got a simple action method that lists some data from a repository. The view for this action method uses simple paging. The URL can be clicked on, or entered as server:port/product/2 where 2 is the page number. If the user enters in a page number that's greater than the number of pages of data, I want to redirect the user to server:port/product/1 first and the notify them they were redirected. The redirecting part works, but I can't seem to find a way to get the value passed to the action method.
EDIT: I used QueryString incorrectly in this question, what I really want is the parameter passed to the action method.
ProductController
public ActionResult List(int page =1)
{
ProductsListViewModel model = new ProductsListViewModel();
model.Products = _repository.Products.OrderBy(x => x.ProductId)
.Skip((page -1) * 4)
.Take(4);
model.PagingInfo = new PagingInfo()
{
CurrentPage = page,
ItemsPerPage = 4,
TotalItems = _repository.Products.Count()
};
//this correctly redirects
if (page > model.PagingInfo.TotalPages)
{
return RedirectToAction("List", new { page = 1 });
}
return View(model);
}
JavaScript
var pageParam = "#Request.QueryString["id"]"
var pageTotal = "#Model.PagingInfo.TotalPages";
var pageCurrent ="#Model.PagingInfo.CurrentPage";
console.log('this is the current page: ' + pageCurrent);
console.log(pageTotal);
console.log(pageParam);
function notifyRedirect(pageTotal, pageParam) {
if (pageParam > pageTotal) {
alert('you entered ' + pageParam + ', an invalid page parameter and were redirected');
window.location = '/Product/List/1';
}
}
notifyRedirect(pageTotal,pageParam);
Routes
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
);
When the page loads, the pageTotal and pageCurrent variables are printed to the console, but I get an empty string when trying to get the QueryString value. Thinking that maybe I had the name of the parameter wrong, I decided to use the integral index of the QueryString and was presented with the error:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
How is it that http://localhost:49997/product/list/2, the fully qualified URL still gives me an empty QueryString value? How can I use JS to notify the user of the redirect?
Perhaps I'm missing something, but it seems like your question is "How do I get a query string value from a URL without a query string."
Both your redirect URL, /Product/List/1 and your last URL mentioned, http://localhost:49997/product/list/2, have no query string, so any attempt to access anything in Request.QueryString is going to return null.
If you need something in the query string on the redirect then you need to add that to the redirect URL:
window.location = '/Product/List/1' + ((pageParam != '') ? '?id=' + pageParam : '');
Change the parameter name of the action method from page to id to agree with MapRoute. Then you don't need the first MapRoute, if you don't skip the name of the action in the url.
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.
I am altering an ASP.NET, MVC, C# application but a routes.MapRoute entry isn't working as expected. In my Global.asax.cs file I have the following two routes -
routes.MapRoute(
"MyRoute1", // Route name
"{controller}/{action}/{something}/{name}/{id}/{myParameterA}",
new { controller = "MyController", action = "MyActionA", category = "something", name = "name", id = "id", myParameterA = "myParameterA" });
routes.MapRoute(
"MyRoute2", // Route name
"{controller}/{action}/{something}/{name}/{id}/{myParameterB}",
new { controller = "MyController", action = "MyActionB", category = "something", name = "name", id = "id", myParameterB = UrlParameter.Optional } );
The code in my controller looks like this -
public ActionResult MyActionA(string something, string name, string id, string myParameterA)
{
//do cool stuff!
}
public ActionResult MyActionB(string something, string name, string id, string myParameterB)
{
//do awesome stuff!
}
When I call MyActionB, the final parameter myParameterB is coming into the Controller as null even when the parameter is in the URL - (example: /MyController/MyActionB/aThing/aName/123/456).
I do want the final parameter ('456' in my above example) to be optional.
MyActionA is working fine.
Any suggestions would be appreciated!
Also, is there a good reference out there on how routes.MapRoute works?
Thank you!
This is because there is nothing to distinguish between those 2 routes once you replace the parameters with strings in the route itself. If you add a static part to the routes you should be able to differentiate between them.
routes.MapRoute(
"MyRoute1", // Route name
"{controller}/{action}/{something}/{name}/{id}/firstroute/{myParameterA}",
new { controller = "MyController", action = "MyActionA", category = "something", name = "name", id = "id", myParameterA = "myParameterA" });
routes.MapRoute(
"MyRoute2", // Route name
"{controller}/{action}/{something}/{name}/{id}/secondroute/{myParameterB}",
new { controller = "MyController", action = "MyActionB", category = "something", name = "name", id = "id", myParameterB = UrlParameter.Optional } );
See if that works.
Not sure but I think swap the two around, when you set "myParameterA = "myParameterA"" on the first, you're assigning a default value, when you pass /MyController/MyActionB/aThing/aName/123/456 the url is mapped to the first, but the number 456 is not compatible with the default string value - and so is passed as null.
EDIT: oh and for a good reference, the Apress Pro MVC 3 has an excellent chapter on this - Safari Informit.
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