Edit: I found the answer, but it meant abandoning the use of HtmlActionlink in favor of doing this (the "blah" parameters from my original post now being subbed in for what I actually needed):
<a href="#Url.Action("LinkedDetails",
new
{
controller = "LGDetails",
findByString = item.AccounNumber
})">#item.LastName</a>
This does exactly what I want. Trying to accomplish the same thing with HtmlActionLink results in one error or another no matter what I tried:
#Html.ActionLink(item.LastName,
"../LGDetails/LinkedDetails",
new
{
controller = "LinkedDetails",
findByString = item.AccounNumber
})
result: Value cannot be null or empty.
Parameter name: linkText
Trying like this:
#Html.ActionLink(Model.LastName .....
Result:
System.Collections.Generic.IEnumerable' does not contain a definition for 'LastName' and no extension method 'LastName' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?)
etc etc. Always one of those errors regardless.
And yes, I tried every single thing suggested here, and an equal number of other things found elsewhere (which is how I found the answer I did use, it was posted by another person having the same problem).
Despite a lot of searching, I can't seem to figure out how to do what seems like it should be basic.
This works fine:
#Html.DisplayFor(modelItem => item.LastName)
But I want to display the LastName field as the linked text inside an Html.ActionLink like this:
#Html.ActionLink(item.LastName, "blah", "blah")
But nothing works. Doing it like the above gives me a compilation error:
The type arguments for method
'System.Web.Mvc.Html.DisplayExtensions.DisplayFor(System.Web.Mvc.HtmlHelper,
System.Linq.Expressions.Expression>)'
cannot be inferred from the usage. Try specifying the type arguments
explicitly
I've tried it like this:
#Html.ActionLink(#Html.DisplayFor(modelItem => item.LastName), "blah", "blah")
and other variations thereof where it is nested. That doesn't work either (won't compile) with the error "no overload method for actionlink.."
I feel like this should be simple. Yes, I'm very new to C# and MVC.
you need to use this overload of Html.ActionLink:
#Html.ActionLink(string LinkText,string ActionName,string ControllerName)
do like this:
#Html.ActionLink(Model.LastName, "ActionName","ControllerName")
Updated:
then do like this, as your Model is IEnumerable:
#foreach(var item in Model)
{
#Html.ActionLink(item.LastName, "ActionName","ControllerName")
}
If Model is Single like this:
#model MyCompany.LGCustData
then it should be lke this:
#Html.ActionLink(Model.LastName, "ActionName","ControllerName")
#Html.ActionLink(#Model.AccounNumber....) works in case someone ends up here just like me.
this is a breaf description of how you should use an actionlink
Html.ActionLink("link title",
"ActionMethod",
"ControllerName",
null, // <-- Route arguments.
null // <-- htmlArguments
)
try something like this:
#Html.DisplayFor(Model.LastName, "actionMethod","controllerName",new{Model.LastName});
*if the case you want to add some parameters to your route, following the standard convention:
/controller/action/parameter
otherwise
#Html.DisplayFor(Model.LastName, "actionMethod","controllerName");
For me I simply convert the "dynamic text" before in a string with String.Format() function like this
<ul>
#foreach (var user in ViewBag.users )
{
string complete_name = String.Format("{0} {1}", user.Firstname, user.Lastname);
<li>#Html.ActionLink(complete_name, "Details", new { Id = user.Id })</li>
}
</ul>
On my computer it works very fine.
Just use
#Html.ActionLink(Html.DisplayNameFor(model => model.LastName).ToHtmlString(), "blah", "blah")
Related
On the Home View I'm generating a number of links:
<ul class="nav navbar-nav">
#foreach (var item in ViewBag.RegList)
{
<li>#Html.ActionLink((string)item.registryName, "Index", "Registry", new { item.registryName }, new { item.registryID }) </li>
}
</ul>
I don't get - how do I set params in ActionLink for my controller and where they go from there?
That's how I defined Index in me controller:
public async Task<ActionResult> Index(object attr)
But in attr goes only object, which when casted to string becomes null. If the orgignal type is string - then also null.
How do I transfer a parameter? Or I'm casting value to the wrong type?
Also I don't understand - what must fourth parameter of ActionLink (routeValues) be?
Method that I'm using: https://msdn.microsoft.com/en-us/library/dd504972(v=vs.108).aspx
Or this one: https://msdn.microsoft.com/en-us/library/dd493068(v=vs.108).aspx
If you look at the created link they will contain a set of query string parameters
"https://some.where/controller/SomeAction/7788?extraParam1=foo&extraParam2=bar"
The standard routing config of MVC makes the parameter "id" part of the local path ("7788" in the example), whereas additional parameters are added to the query string (after the question mark).
Your method signature to the action should be something like
public async Task<ActionResult>
SomeAction(string id, string extraParam1, string extraParam2)
to get the parameters in my example link.
I'm trying to get my WebGrid to use the name of my entity as a link. If I just do this:
grid.Column("Name"),
The grid displays the name of the entity in each row of the grid:
However, I want the name to appear as a link. The closest I've come to getting this working is doing this:
grid.Column("Name", format: (item) => #Html.ActionLink("Edit", "Edit", new { id = item.Id })),
But, as you can see, every name is Edit. How can I get the actual object name there? I tried this, but I get an error (the only difference is that I'm trying to use item.Name in place of "Edit" as the first parameter of the ActionLink method):
grid.Column("Name", format: (item) => #Html.ActionLink(item.Name, "Edit", new { id = item.Id })),
Error: TrackerJob>>' has no applicable method named 'ActionLink' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
format is func which have input parameter of type dynamic and as result type of item.Name is dynamic too at compile time. And as error says use following code :
grid.Column("Name", format: (item) => #Html.ActionLink((string)item.Name, "Edit", new { id = item.Id })
Try swapping the arguments around?
grid.Column("Name", format: (item) => #Html.ActionLink("Edit", item.Name, new { id = item.Id }))
After First Comment
Try using an overload of ActionLink with more parameters (from here):
public static MvcHtmlString ActionLink(
this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
RouteValueDictionary routeValues,
IDictionary<string, Object> htmlAttributes
)
As an overload can become ambiguous with just strings. Alternatively use named parameters when defining the ActionLink.
Tried looking into GetSelectLink()? More on it here: http://weblogs.asp.net/andrebaltieri/archive/2010/11/02/asp-net-mvc-3-working-with-webgrid-part-2.aspx
Personally, I would stick with making the tables yourself - when they get more customized, I find it less confusing, but that is my opinion.
EDIT:
You could do something like this, but again I stress that you are kind of getting away from the point of this being 'simple':
item.GetSelectLink(String.Format("<a href='{0}'>{1}</a>", Url.Action("Edit", new { id = item.Id }), item.Name))
I want the ability to grab an anonymous type from my view, that was established by the corresponding controller. According to this article, such an ability becomes possible in C# 4.0 with the 'dynamic' keyword. However, when I try to find an actual example I find answers ranging from it kinda 'is possible' to it kinda 'is not possible.'
In my case, I have a controller creating this:
XElement headings = XElement.Parse(part.TagList);
var items = from heading in headings.Descendants("heading")
select new {
name = heading.Attribute("name").Value,
tags = heading.Attribute("tags").Value,
content = shapeHelper.List() //This is a dynamic object!!!
}; //can I add 'as dynamic;' here????
In short it would be nice if, without a static type, my view could simply reach into the model like this:
#{
//Currently this next line returns an error saying that
//'object' contains no method 'Count'
int foo = Model.items.Count();
//This 'foreach' works.
foreach(dynamic lineItem in Model.items){
//But this does not work. Gives another "'object' has no definition for 'name'"
<p>#lineItem.name</p> }
}
Possible?
Not sure it's exactly what you're looking for, but you could always use the ViewBag:
Controller
ViewBag.Items = from heading in headings.Descendants("heading")
select new {
name = heading.Attribute("name").Value,
tags = heading.Attribute("tags").Value,
content = shapeHelper.List()
};
View
ViewBag.Items.First().content;
[update]
I'm sorry, i should tag this question
as MVC-2, I pass result of query into
view's model, so i must specify type
of my model in View's header
defintion. I declare it like this:
Inherits="System.Web.Mvc.ViewPage<IQueryable<dynamic>>"
how ever nothing changed and none of
answers doesn't work for me :(.
finally i used an ModelView class as
helper to put my query result in it.
:(
[/update]
I have a query like this:
IQueryable<dynamic> result = from d in KiaNetRepository.KiaNetEntities.Discounts
where d.AgentTypeID == agentTypeId
select new { d.Category, d.DiscountValue, d.PriceConfige };
then i retrive value in my view like this:
foreach(var item in result){
Category cat = item.Category; // throws exception 'object' does not contain a definition for 'Category'
//...
}
note that type of query as IQueryable is anonymouse class...
Try to declare names explicitly:
select new { Category = d.Category, DiscountValue = d.DiscountValue, PriceConfige = d.PriceConfige }
If you are not forcing result to be of IQueryeable<dynamic> for any specific reason, I would recommend using var result = .... This will let the compiler make result of type IQueryable<T> with T the type of the anonymous class that you create using new { ... } in the select. There is no necessity for using dynamic from the code that you show here.
If you replace the inappropriate declaration IQueryable<dynamic> by var, sure it works, I've just also tested it.
Your problem is that your foreach loop being in the view page gets compiled into a separate assembly. Since anonymous types are internal the dynamic doesn't see it because of the permissions don't allow it.
Simplest fix is to call ToList() on your query statement and then select each anonymous type and copy parameters to a declared class or expandoobject.
I am using ASP.NET MVC along with JQueryMobile in a web app. I want to generate a link:
Previous
I have a helper extension method that lets me do:
<%= Html.ActionLink<WhateverController>(c => c.Previous(),
"Previous",
new { data-role = "button", data-icon="arrow-l" } ) %>
Except data-role and data-icon are not valid as property names in C#. Using #data-role doesn't work either.
Is there any syntax to work around this? Or am I stuck with creating a more specialized helper that knows the correct attribute names.
You should be able to use IDictionary<string, object> instead of the anonymous object:
Html.ActionLink<WhateverController>(c => c.Previous(),
"Previous",
new Dictionary<string, object>
{
{ "data-role", "button" },
{ "data-icon", "arrow-l"}
})
In addition to svick's response, we made a neat change in ASP.NET MVC 3 where properties that have an underscore in them will automatically have the underscores converted to dashes.
So, if you have code like this:
<%= Html.ActionLink<WhateverController>(c => c.Previous(),
"Previous",
new { data_role = "button", data_icon="arrow-l") %>
It will render the markup with dashes:
Previous
Because that character is also the subtraction/unary minus operator you can't use it in an identifier. I think the custom helper method is probably your best bet.