Use Action link and query string - asp.net-mvc

I want to use an actionlink to call a controller. My URL is
localhost:16252/Concert/Index/9.
I want to call create controller and send id (9) to the controller. How to access the id (9) from address bar by actionlink?

ActionLink has one overload that allows you to specify routevalues
MSDN Link here
#Html.ActionLink("LinkText", "Action", "Controller", new {Id= 9}, null)

For Passing from View you have to use overload which takes parameter of RouteValueDictionary:
#Html.ActionLink("Link Text","MyAction", "My", new {id= 9},null)
and in your controller:
public class MyController
{
public ActionResult MyAction(int id)
{
// do something
return View();
}
}
Using this overload of Html.ActionLink()

Related

Override RedirecToAction method

Is there a way to extend the RedirectToAction method on mvc 5 for accepts masterName parameter. I'm looking for something like this:
RedirectToAction(actionName: "Index", controllerName: controllerName, masterName: "_Layout");
Can you guys help me?
You can pass route values.
return RedirectToAction(actionName: "Index", controllerName: controllerName, new {masterName = "_Layout"});
The action method should have a parameter with name masterName. This parameter will then receive the value given here. You can then inside the controller action pass on the parameter to the view.
public ActionResult Index(string masterName)
{
// Other code
return View("Index", masterName);
}

MVC route constraint custom attribute

I'd like to setup a custom route constraint that would allow me to decorate a controller with an attribute so that I don't have to pass in string to the route and remember to update it with new controller names.
I thought I could setup use the IRouteConstraint but I can't seem to get the attribute. Perhaps I'm just missing something obvious here.
routes.MapRoute("test",
"foo/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = new TestConstraint()}
);
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
public class TestConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
return false;
}
}
[AttributeUsage(AttributeTargets.Class)]
public class CustomConstraintControllerAttribute : Attribute
{
}
[CustomConstraintController]
public class TestController : Controller
{
public ActionResult Index()
{
return View();
}
}
Edit:
Current Method:
routes.MapSubdomainRoute("Store",
"{store}/{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
new {controller = "StoreHome|Contacts|..." }
);
This route configuration ensures that a url must match subdomain.test.com/GiggleInc/Contacts or subdomain.test.com/GiggleInc/StoreHome.
subdomain.test.com/GiggleInc/StoreHome
MapSubdomainRoute /{store} /{controller}/{action}/{id}
This method requires that each controller that should be used this way must be added to the controller constraint.
As I mentioned in the comments, I want to replace the hard coded strings for an attribute or something similar.
First, thank you for this sweet line of code I didn't know was possible:
constraints: new { controller = "StoreHome|Contacts" }
I didn't know I could filter my MapRoute to a list of Controllers so easily.
Second, you don't need to implement a custom IRouteConstraint for this.
MVC offers the Attribute-Routing you are looking for.
You may even include Default/Optional Values, just like in your MapRoute.
Decorate your Controller Class like so:
[RoutePrefix("{store}/Test")]
[Route("{action=Index}/{id?}")]//Without this, you need to define "[Route]" above every Action-Method.
public class TestController : Controller
{
public ActionResult Index(string store)//Adding "string store" is optional.
{
return View();
}
}
That's it.
Remember to add the "store" Parameter in all your Actions under each Controller (but it is not Required).
Note:
If you use Attributes instead of MapRoute, then you will not be able to hit the Controller without the "store" Prefix.
With the Custom and Default MapRoutes, you could have accessed your controller either way.
By decorating your Controller with these Attributes, you now force it to only use this exact path.
This may be what you want, but if you start IIS Express from Visual Studio on one of your Views, it will not find it, because Visual Studio doesn't know to add the RoutePrefix for you.
See this link for more information about Attribute-Routing:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
Try this...
public class TestRouteAttribute : RouteFactoryAttribute
{
public TestRouteAttribute(string template) : base(template) { }
public override RouteValueDictionary Constraints
{
get
{
var constraints = new RouteValueDictionary();
constraints.Add("TestConstraint", new TestConstraint());
return constraints;
}
}
}
Then you should be able to decorate your action methods using [TestRoute]
By the way, would love to know how to accomplish this in asp.net core if anyone knows.

overload views in MVC?

I want to have links http://localhost:2409/Account/Confirmation/16 and that link http://localhost:2409/Account/Confirmation/ (without parametr). But with this action methods, it isn't working. Why?
public ActionResult Confirmation(int id, string hash)
{
Some code..
return View();
}
second, I just want to return View, if parametr is empty.
public ActionResult Confirmation()
{
return View();
}
Error (translated):
The current request for action on a controller Confirmation
AccountController is ambiguous between the following methods of
action: System.Web.Mvc.ActionResult Confirmation (Int32,
System.String) for type TC.Controllers.AccountController
System.Web.Mvc.ActionResult Confirmation () for type
TC.Controllers.AccountController
You cannot have multiple actions with the same name using the same HTTP verb (in your case GET.) You can name your actions differently but this means the link will change or you can use different VERB but this can also leads to other problems like you cannot just enter the link in your browser.
What you should do is to change your id to be optional with int? and merge your two actions into one:
public ActionResult Confirmation(int? id, string hash)
{
if(id.HasValue)
{
//Some code.. using id.Value
return View();
}
//There was no Id given
return View();
}
You may also need to allow in your route that the id is optional. If you are using the default routes this should be the default setting:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
There is no need to make 2-methods for it. Your HTTP request get confused that which ActionMethod should be called on both cases;
http://localhost:2409/Account/Confirmation/16
http://localhost:2409/Account/Confirmation/
Instead of all this, just create a single method. Make its parameter optional or assign some default value to the parameters. Here are 2-examples to understand it.
// 1. Default value to paramter
public ActionResult Confirmation(int id = 0, string hash = null)
{
//Some code..
return View();
}
// 2. Make id optional
public ActionResult Confirmation(int? id, string hash)
{
//Some code..
return View();
}
You can adopt any one approach from them.

overload action for number of parameters in asp.net mvc

Is it possible to overload the action methods based on number of parameters in request?
Eg:
1.
domain.com/List/Filter/ByName
invokes -> public ActionResult Filter(string criteria1)
2.
domain.com/List/Filter/ByName/ByRanking
invokes -> public ActionResult Filter(string criteria1, string criteria2)
I'm using asp.net mvc2.
Action methods cannot be overloaded based on parameters because there would be no reasonable way to disambiguate a URL into multiple overloaded methods.
What you can do, though is either this:
public ActionResult Filter(string criteria1, string criteria2)
and then check whether criteria2 is null to filter only by name.
Alternatively, you can use ActionNameAttribute to decorate your action methods
[ActionName("FilterByName")]
public ActionResult Filter(string criteria1)
[ActionName("FilterByNameAndRanking")]
public ActionResult Filter(string criteria1, string criteria2)
and then use that name in route registration. This approach, however, can lead to much confusion.
If I'm not mistaken the best way to do this would be to add two different controller methods and map them to two different Urls.
public ActionResult Filter1(string criteria1);
public ActionResult Filter2(string criteria1, criteria2);
Then you have two route definitions:
This will map this URL List/Filter/xxCriteria/ to the first controller
routes.MapRoute(
"Filter", // Route name
"{controller}/Filter/{criteria1}", // URL with parameters
new { controller = "List", action = "Filter1", criteria="" } // Parameter defaults
);
This will map this URL List/Filter/xxCriteriaName/xxxCriteriaRank to the second controller. Without this route you could still map a url to the second method, but it would look like : List/Filter/?criteria1=xx&criteria2=xx
routes.MapRoute(
"Filter2", // Route name
"{controller}/Filter/{criteria1}/{criteria2}", // URL with parameters
new { controller = "List", action = "Filter2", criteria1 = "", criteria2 = "" } // Parameter defaults
);
Hope it helped.

asp.net mvc with optional parameters and partial views

i have:
AlbumsController
PhotoRepository
Index.aspx (view)
inside of Index.aspx, i have a partial view call AlbumControl. I want to update this via ajax and ajaxhelper.
the issue is that i want the ability to do the following:
http://www.mysite.com/Albums
http://www.mysite.com/Albums?FilterTag=Birthdays
when i do this, i get the following error:
The current request for action 'Index' on controller type 'AlbumsController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Index(System.String) on type Controllers.AlbumsController
System.Web.Mvc.ActionResult Index() on type Controllers.AlbumsController
i would have thought that asp.net mvc would have figured it out where if i pass in a parameter in the querystring it would go to the Index(string Tag) method and if i didn't pass in a parameter, it would go to Index().
suggestions?
The problem is that the MVC Routing Engine can't tell the difference between:-
1) Calling Index()
and
2) Calling Index(string tag) with tag = null
That's why it says the request is ambiguous.
You can just do:-
public ActionResult Index(string tag)
{
if(String.IsNullOrEmpty(tag))
{
// index code goes here
return View("Index");
}
else
{
// code to handle filtered view goes here
return View("Tag");
}
}
or you can force the parameter to be required with a custom attribute:-
ASP.NET MVC ambiguous action methods
or you can set up routes so that Albums and Albums?FilterTag=X explicitly go to different actions (Incidentally, I'd recommend "Albums" and "Albums/X"):-
routes.MapRoute("AlbumsIndex", "Albums",
new { controller = "Albums", action = "Index" });
routes.MapRoute("AlbumsTag", "Albums/{tag}",
new { controller = "Albums", action = "Tag", tag = "" });
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" );
and
public ActionResult Index() { ... }
public ActionRestlt Tag(string tag) { ... }

Resources