Get id from clicked url - asp.net-mvc

It is necessary for me at a choice the user of a subject of a forum on the page from a database contents of the chosen subject were loaded on the page. I will describe how I approached to the solution of this task. This code presents forum threads:
<a href='Home/ThreadView' id='1'>About all</a>
<a href='Home/ThreadView' id='2'>Cars</a>
ThreadView action has code:
[HttpGet]
public ViewResult ThreadView(int id)
{
ViewData[ThreadViewSelector] = Thread.GetThreadView(id);//Thread is a model.
return View();
}
When I click on any link an error occurs:
Parameters dictionary contains record with value NULL for parameter "id" of type "System.Int32"
How to solve this problem ?

The ID attribute in your link is the id of the HTML element... so, that id could be useful if you want to do something with javascript.
With your current code, the id is never sent to the controller action, that is why the error you are seeing. You need to put the ID in the href attribute along with the Controller/Action.
You have 2 options to pass the id to your controller action:
If you have the out-of-the-box routing rules you can use:
<a href='Home/ThreadView/1' id='1'>About all</a>
You can send it via query string this way:
<a href='Home/ThreadView/?id=1' id='1'>About all</a>
EDIT:
The element id is not required in order to have the routing working.
Instead of doing this manually, you could use one of the Razor Helpers:
#Html.ActionLink("About all", "Home", "ThreadView", new { id = 1})
If you need to add some attributes to the link element, besides the routing parameters:
#Html.ActionLink("About all", "Home", "ThreadView", new { id = 1}, new { #class = "redLink", id="aboutall"})

Related

Insert current URL into #Html.RouteLink parameter to build a link

I am probably going about this the wrong way as i'm a noob to .NET MVC, but is there a way to insert the current url as a parameter into an #Html.Routelink?
I'm passing a partial view into a page to display a list of subcategories based off of the current category.
Here is my controller logic:
public PartialViewResult SubcategoryMenu(string category)
{
IEnumerable<string> subcategories = repository.Products
.Where(x => x.SubCategory.Category.CategoryName == category)
.Select(x => x.SubCategory.SubCategoryName)
.Distinct()
.OrderBy(x => x);
return PartialView(subcategories);
}
Here is my partial view which I'm trying to get the current category url into:
#model IEnumerable<string>
#foreach (var link in Model)
{
#Html.RouteLink(link, new
{
controller = "Product",
action = "List",
category = "INSERT CURRENT URL HERE",
subcategory = link,
page = 1
}, new { #class = "btn btn-block btn-default btn-lg" })
}
When the page displays, all products and categories are listed, no problem. When I click a Category, the URL is http://localhost/Category2 which is what I want.
Click a category, then all of the associated subcategories display in a separate div based on the linq query in the controller just fine.
However, to properly display the products, the url generated for the subcategory view needs to be http://localhost/Category/Subcategory and no matter how I tweek the #Html.RouteLink or even an #Html.Actionlink, all I can get is http://localhost/Subcategory If i pass in text into the #Html.Routelink for controller= "something" that will display http://localhost/something/Subcategory so I've been trying to get the current URL which matches the required category passed into the subcategory #Html.Routelink with no success.
If there is a way to insert the current URL into the subcategory RouteLink it would solve my woes. If there is a way to accomplish, or a better way to do so, please help.
Thank you all!
RouteLink and ActionLink use the RouteTable to build outgoing URLs, so it is the RouteTable you need to modify to customize URLs, not the RouteLink configuration.
You can do this many ways, but the most flexible way to make URLs that are driven off of database data is to subclass RouteBase.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object

I've seen a lot topics with such a problem, but could not find mine. After this error it specifies a source:
#{
Line 4: ViewBag.Title = "Edit product: " + #Model.Name;
Line 5: Layout = "~/Views/Shared/_MasterLayout.cshtml";
Line 6:
}
It happens after I click on the name of my product from a View
#Html.ActionLink(item.Name, "Edit", new { item.ProductID })
The link becomes
http://localhost:31363/Master/Edit?ProductID=1
And I am not able to see my view, however, if I edit the link manually to
http://localhost:31363/Master/Edit/1
It works. So, what should I fix to make it work either in first way or automatically in the second one? I don't have any special routes right now, it is a default one coming with Mvc4 application.
This should solve the problem:
#Html.ActionLink(item.Name, "Edit", new { id = item.ProductID })
Explanation
In your code, you are creating a link with a ProductID parameter because
#Html.ActionLink(item.Name, "Edit", new { item.ProductID })
is equal to:
#Html.ActionLink(item.Name, "Edit", new { ProductID = item.ProductID })
Since there isn't a parameter named ProductID in the default route, it is added to querystring. Also your Edit action probably has an integer parameter named id like this:
public ActionResult Edit(int id)
Since this parameter is not optional or nullable, request cannot be mapped to this action and you get the error. So parameter names matter because ASP.NET MVC can't figure it out by itself.

How can I name a form with Html.BeginForm()?

How do I give a name to a form in ASP.NET MVC using Html.BeginForm()? I want only the name, not the action or controller name because I want to post it through Javascript. I think it should be something like Html.BeginForm(id = "frm").
I tried the following:
Html.BeginForm(null,null,new{id="frm",name="frm})
Html.BeginForm(new{#id="frm",#name="frm})
But the above code produces output like this:
<form action="/Main/Index/Id?name=Id" method="post">
Html.BeginForm(null, null, FormMethod.Get, new { name = "frm", id = "frm" })
You'll need to catch the form submit with your JavaScript
Using MVC2, this is what worked for me:
<% using (Html.BeginForm("Index", "Home", null, FormMethod.Post, new {#id = "myForm", #name = "myForm"})) {%>
#HTML.BeginForm("Target-ViewName where you want to post the page","Controller Name",new {#name="Name of the Form", id="ID of the Form"})
{ //form here
}
Taken from this answer: How to pass in ID with Html.BeginForm()?
Can you not just do:
Html.BeginForm(new {#id="Id", #name="Id"});
It can pay to search SO for answers as I've found many things I want to ask have already been encountered.

How to pass query string parameter in ActionLink in MVC

I am having following action link:
<%= Html.ActionLink("Check this", "Edit", "test",
new { id = id }, new { style = "display:block" })%>
How do I include data=name as query string. Some thing like this:
link?data=name
4th parameter of Html.ActionLink can have any number of properties:
<%= Html.ActionLink("Check this", "Edit", "test",
new { id = id, data=name }, new { style = "display:block" })%>
These properties are inserted into URL based on routing, but if the property name cannot be matched into any route it is added as URL GET parameter.
So if you have standard route {controller}/{action}/{id}, you will get the URL:
test/Edit/[id]?data=[name]
from the above code.
Pass Query String By this way
#Html.ActionLink("Delete Record", "Home", "Delete", new { id=Id},null)
By above code you will get the url like(Suppose Id=1): /Home/Delete/1
and if you want to add more parameters to query string then:
#Html.ActionLink("Delete Record", "Home", "Delete", new { id=Id, Name=name},null)
By above code you will get the url like(Suppose Id=1 and Name=India) :
/Home/Delete/1?Name=India
I got tired of banging my head against a wall with the html.actionlink. Works great when you just want to route it against straightforward routing calls, but absolutely refuses to cooperate when you want to add a simple querystring at the end.
I don't an ID at then end, I want to be able to add some kind of actual Querystring with the "?".
So anywhere I needed a Querystring I switched to using the url.action inside the anchor tag.
<a href='#url.action("Action","route")?Parameter=Value' >Text for Link Name</a>
At least it works and I can stop getting headaches over something that should have been a very simple task. Someone needs to get their heads out of their butts and make the ActionLink work properly for Querystrings in the MVC routing.
I know this is kind of old question but.
In case the below code doesn't generate the <a href="/?param=value" />.
<%= Html.ActionLink("Text", "Action", "Controller", new { param=value }, null)%>
I would advice checking whether you action has at least one [Route] attribute (I used [Route("/")] for example).
Hope it helps.

asp.net mvc Html.ActionLink() keeping route value I don't want

I have the following ActionLink in my view
<%= Html.ActionLink("LinkText", "Action", "Controller"); %>
and it creates the following URL http://mywebsite.com/Controller/Action
Say I add an ID at the end like so: http://mywebsite.com/Controller/Action/53 and navigate to the page. On this page I have the markup I specified above. Now when I look at the URL it creates it looks like this:
http://mywebsite.com/Controller/Action/53 (notice the addition of the ID)
But I want it to remove the ID and look like it did originally, like this http://mywebsite.com/Controller/Action (notice no ID here)
Any ideas how I can fix this? I don't want to use hard coded URLs since my controller/actions may change.
The solution is to specify my own route values (the third parameter below)
<%= Html.ActionLink("LinkText", "Action", "Controller",
new { id=string.Empty }, null) %>
It sounds like you need to register a second "Action Only" route and use Html.RouteLink(). First register a route like this in you application start up:
routes.MapRoute("ActionOnly", "{controller}/{action}",
new { controller = "Home", action = "Index" } );
Then instead of ActionLink to create those links use:
Html.RouteLink("About","ActionOnly")
The problem is the built in methods take input from the URL you are currently on as well as what you supply. You could try this:
<%= Html.ActionLink("LinkText", "Action", "Controller", new { id = ""}) %>
That should manually wipe the id parameter.
Don't know why, but it didn't work for me (maybe because of Mvc2 RC). Created urlhelper method =>
public static string
WithoutRouteValues(this UrlHelper helper, ActionResult action,params string[] routeValues)
{
var rv = helper.RequestContext.RouteData.Values;
var ignoredValues = rv.Where(x=>routeValues.Any(z => z == x.Key)).ToList();
foreach (var ignoredValue in ignoredValues)
rv.Remove(ignoredValue.Key);
var res = helper.Action(action);
foreach (var ignoredValue in ignoredValues)
rv.Add(ignoredValue.Key, ignoredValue.Value);
return res;
}
If you either don't know what values need to be explicitly overridden or you just want to avoid the extra list of parameters you can use an extension method like the below.
View
The implementation details are in this blog post
I explicitly set the action name as "Action/". Seems a little like a hack but it's a quick fix.
#Html.ActionLink("Link Name", "Action/", "Controller")
Another way is to use ActionLink(HtmlHelper, String, String, RouteValueDictionary) overload, then there are no need to put null in the last parameter
<%= Html.ActionLink("Details", "Details", "Product", new RouteValueDictionary(new { id=item.ID })) %>
The overloads of Html.ActionLink are changed on the later versions of MVC. On MVC 5 and above. This is how to do this:
#Html.ActionLink("LinkText", "Action", "Controller", new { id = "" }, null)
Note I passed "" for id parameter and null for HTMLATTRIBUTES.
I needed my menu links to be dynamic. Rather than implement a lot of extra code and routing for every single page I simple dispensed with the HTML helper.
#item.MenuItemName

Resources