Reputation: 22212
I got an HtmlHelper to spit out html for my page title and description.
public static class HeaderHelper
{
public static MvcHtmlString StandardHeader(this HtmlHelper htmlHelper,
string title,
string description="")
{
var tbSection= new TagBuilder("div");
tbSection.AddCssClass("page-header");
var tbTitle = new TagBuilder("h2") {InnerHtml = title};
if (!string.IsNullOrEmpty(description))
{
var tbDescription = new TagBuilder("p") {InnerHtml = description};
tbSection.InnerHtml = string.Concat(tbTitle, tbDescription);
}
else
{
tbSection.InnerHtml = tbTitle.ToString();
}
return MvcHtmlString.Create(tbSection.ToString());
}
}
It works good for
@Html.StandardHeader("View Employees")
and
@Html.StandardHeader("Edit Employee","...some description...")
But when I use ViewBag values like
@Html.StandardHeader(ViewBag.Title)
or
@Html.StandardHeader(ViewBag.Title.ToString())
So the question: how can we pass in ViewBag.Title
into an HtmlHelper?
There is red line below my @Html.StandardHeader(...)
statement.
It is a Compilation Error
Compiler Error Message: CS1973: 'System.Web.Mvc.HtmlHelper' has no applicable method named 'StandardHeader' 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.
I have tried some other variation:
@{
var test = "test";
var title = string.Format("Welcome {0}", ViewBag.Title);
}
@Html.StandardHeader(test) // works
@Html.StandardHeader(title) // won't work :(
Also, I have made sure ViewBag.Title
is not null.
Just a few more comments on the solution provided.
Basically, we have to do an explicit cast.
All C# object has a .ToString()
method. But not every one can be cast to a string. A ViewBag
value is essentially an object, a .ToString()
on which is not a cast.
As for why we have to use string
instead of var
to explicitly declare the variable,
string title = string.Format("Welcome {0}", ViewBag.Title);
I got a good answer in my separate SO question.
Direct quote from there.
All expressions are evaluated at runtime, with the occasional exception of some operations on compile time literals.
So: if at least one of the parameters is dynamic, the entire expression is treated as it was dynamic and evaluated on runtime.
Hope this update helps.
Upvotes: 6
Views: 11666
Reputation:
You need to cast the ViewBag
property (because ViewBag
is dynamic
).
@Html.StandardHeader((string)ViewBag.Title)
and in the second example
@Html.StandardHeader((string)title)
or explicitly declare the variable as a string
rather that var
@{ string title = string.Format("Welcome {0}", ViewBag.Title); }
@Html.StandardHeader(title)
Upvotes: 9