Passing parameter to controller in MVC with no changes in url - c#

I have a controller:
public ActionResult Index(string id)
{
ViewBag.ReloadedFromEmailForm = id;
return View();
}
The controller can be called from RouteConfig (as its default) with param id = null and can be called from some other controller which is returning
return RedirectToAction("Index", "Home", new {id = 1});
Now I want to get that id = 1 but in my url when I turn on app, to set just like regular without any param.
How to achieve that?
Now: localhost:8888/Index/1
What I want: localhost:8888/Index/ (but still I want to fill in ViewBag).

Solved. I didn't realize that property name id already in a route config,and automatically maps in url. All I needed to do was to change my prop to anything else, like foobar :)

Related

In MVC, why does my controller need to receive a "new { id = restaurant.Id }", as opposed to "restaurant.Id"? Are the not both simply int's?

So my mvc controller method here take an int id as an argument. Im wondering why new "{ id = restaurant.Id}" is required and "restaurant.Id" is not sufficient.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Restaurant restaurant)
{
if (ModelState.IsValid)
{
db.Update(restaurant);
return RedirectToAction("Details", new { id = restaurant.Id });
}
return View(restaurant);
}
That is because MVC expects an object from which to retrieve the values to bind to the action parameters. In other words, you could do:
return RedirectToAction("Details", restaurant);
Mvc will crawl your object for properties that match the name and type of your action's arguments and should therefore bind to the restaurant's 'Id' property.
If you just pass the restaurant's Id, though, MVC will crawl the type of whatever you restaurant's id property is.
Hope this helps. If it does, please mark it as the answer ;)

Cannot generate correct links

I have the following code in a razor page:
#Url.Action("ArticleDetails", "Information", new { slug = article.Slug })
The page url where this code is placed has the form of http://localhost/category/6/category-name where 6 is the ID of the category
In the InformationController I have the following actions:
[HttpGet("article/{id}/{slug}")]
public IActionResult ArticleDetails(int id, string slug)
{
// some code ...
return View(data);
}
[HttpGet("article/{slug}")]
public IActionResult ArticleDetails(string slug)
{
// some code ...
return View(data);
}
How can I reach URL of form article/article-slug because #Url.Action(...) that I have in the page always try to reach controller action with id even if ID is not supplied as an anonymous type.
Links take the form of article/6/article-slug instead I want them to be article/article-slug without removing action with id in the controller.
I have noticed that 6 is from the id of the category. Also if I delete the controller action with Id i get the correct format of URL.
When resolving the action you're linking to, the IUrlHelper instance is using the current value of id in your current route (http://localhost/category/6/category-name), which has a value of 6, as you stated in your OP. Because there exists an ArticleDetails action that takes both an id and a slug (which you provide explicitly), the ArticleDetails action that takes both of these parameters is selected.
In order to resolve this, there are a couple of options. The first option is to clear out the RouteData value once you've used it in the action invoked when reaching http://localhost/category/6/category-name. In order to do that, you can use the following code within said action:
RouteData.Values.Remove("id");
I'm not a fan of doing it this way, but it does work. IMO, a better approach would be to simply use different names for the id parameter: e.g. categoryId and articleId in the respective controllers. This both fixes your issue and makes the code more readable in the corresponding actions. Your ArticleDetails action would simply change to:
[HttpGet("article/{articleId}/{slug}")]
public IActionResult ArticleDetails(int articleId, string slug)
{
// some code ...
return View(data);
}
Routing can be finicky when trying to do overloads like this. Your best bet is to use named routes:
[HttpGet("article/{id}/{slug}", Name = "ArticleDetailsIdSlug")]
public IActionResult ArticleDetails(int id, string slug)
[HttpGet("article/{slug}", Name = "ArticleDetailsSlug")]
public IActionResult ArticleDetails(string slug)
Then, in your view:
#Url.RouteUrl("ArticleDetailsSlug", new { slug = article.Slug })
Now, the routing framework doesn't have to try to figure out which route you actually want (and guess incorrectly apparently), as you'd told it exactly which route to use.

Asp.net mvc won't take the razor parameter

I'm developing on a school project where it has gone great so far but the problem has finally arrived.
I have this method in my homecontroller:
[HttpPost]
public ActionResult GetSeatsInShow(int showId)
{
...
return View(realSeatList);
}
In my view I use razor to parse a parameter to the controller and the controller should return the result in an address like this:
http://localhost:1499/Home/GetSeatsInShow/236
That is what it does if I do it on my other controller method called Shows on the following URL:
http://localhost:1499/Home/Shows/1
But on the GetSeatsInShow method will I need to place ?showId= like to snippet right under:
http://localhost:1499/Home/GetSeatsInShow/?showId=236
My razor ActionLink looks like this:
#Html.ActionLink("Vælg", "GetSeatsInShow", new { id = item.Id })
Can't seem to find the problem aftersome the Show method works fine with the same results as the one that doesn't work.
You have a few options.
You're currently passing the parameter as id, not showId, whereas your controller expects a parameter named showId. As a result, by updating your anonymous type you can pass the correct parameter name.
#Html.ActionLink("Vælg", "GetSeatsInShow", new { showId = item.Id })
Alternatively, you can simply pass "id" in your querystring and allow the default MVC binding to work it's magic if you update your controller:
#Html.ActionLink("Vælg", "GetSeatsInShow", new { id = item.Id })
[HttpPost]
public ActionResult GetSeatsInShow(int id)
{
...
return View(realSeatList);
}
You can try this
#Html.ActionLink("Vælg", "GetSeatsInShow", new { id = item.Id, showId = item.Id })
you are taking an input of showId in GetSeatsInShow and in the razor you are passing in id
[HttpPost]
public ActionResult GetSeatsInShow(int id)
{
...
return View(realSeatList);
}

Return action doesn't change URL

I was looking for a way to redirect with POST and the solutions I've found suggest simply using the action's name I want and fill the params. All of this within the same controller (let's call it Home)
[HttpPost]
public ActionResult Zoro(NameOfMyModel model, string stringName)
{
//Do whatever needs to be done
return Foo("bar",123);
}
[HttpPost]
public ActionResult Foo(string Name, int Age)
{
//Code here that use the params
return View();
}
So that works great except that when you look at the url, it doesn't show /Home/Foo, it shows /Home/Zoro. Can I fix this without using RedirectToAction? If I use it, I get this: Home/Foo?Name=bar&Age=123 Which I don't want.
Instead of calling directly calling Foo() use RedirectToAction() with this overload of it.
The way you doing calls the action on server but not actually redirects, if you want the url to change you have to redirect to the action:
return RedirectToAction("Foo", new {Name = "bar", Age = 123});
UPDATE:
As in comments mention how to keep the data temporarily ,you can use TempData[] for it:
TempData["Name"] = bar";
TempData["Age"] = 123;
return RedirectToAction("SomeAction");
and in that action you can get it from TempData:
public ActionResult SomeAction()
{
string Name = TempData["Name"] as string;
int Age - TempData["Age"] as int;
return View();
}
NOTE:
Note that RedirectToAction() only works with actions which are HttpGet, it will not work with HttpPost actions.

Possible to trigger action depending on given params for MVC Controller?

Say I have a controller called User, and I have a Index ActionResult, and then a secondary ActionResult called SetUserInfo. Example below:
public ActionResult Index(int id)
{
var enviorment = Zen.Components.Environment.GetEnvironmentByID(id);
return View(settingsViewModal);
}
//Second action
public ActionResult SetSite(int id, int siteID)
{
var enviorment =
Zen.Components.Environment.GetEnvironmentByID(
new EnviornmentQuery() {EnviormentID = id, SiteID = siteID);
return View(enviorment.Site);
}
Since the url "Settings?id=1" fires the ActionResult "Index", can I get "Settings?id=1&siteID=133" to then let the controller know it has to trigger ActionResult "SetSite" based on the params it was given, or do I have to make them optional in the first ActionResult, OR am I thinking of this all wrong. The route mapping is what is taking me a minute to fully get. I know it can be called as follows "Settings/SetSite?id=1&siteID=133", but wondering if I can do my prior example? If so, is it a bad way to handle it, or not?
You can map a route for it:
routes.MapRoute(
name: "SetSiteRoute",
url: "{controller}/{action}/{id}/{siteID}",
defaults: new { controller = "Settings", action = "SetSite" }
// Important part ^^^^^^^
);
Make sure you put it above your default route so that it takes precedence (routes are processed in order).
This will allow: www.site.com/Settings/1/500 where 1 is the id, and 500 is the siteID.
Although not exactly the answer you may be looking for..
First off, you cant map your route that way. The route cannot contain the ? character, so although you could use an alternative way to call your route using something like
/Settings/{id}/{siteId}
Using the following
/Settings?id={id}&siteID={siteId}
Cant be mapped as a route. However you could easily add the site id property to your Index action such as.
public ActionResult Index(int id, int? siteID)
{
if (siteID.HasValue)
return SetSite(id, siteID);
return null;
}
//Second action
public ActionResult SetSite(int id, int siteID)
{
return null;
}
I know this isnt exactly what you are looking for but will achieve the same result without having to mess around with your routes and urls. (Note i am just returning null so it compiles).
Cheers.

Categories