I've been trying to convert my aspx pages to cshtml and having an issue with rendering partial pages from another folder.
What I used to do:
<% Html.RenderPartial("~/Views/Inquiry/InquiryList.ascx", Model.InquiryList.OrderBy("InquiryId", MvcContrib.Sorting.SortDirection.Descending));%>
I would think that the equivalent would be:
#Html.RenderPartial("~/Views/Inquiry/_InquiryList.cshtml", Model.InquiryList.OrderBy("InquiryId", MvcContrib.Sorting.SortDirection.Descending))
This is obviously not working, I am getting the following error.
CS1973:
'System.Web.Mvc.HtmlHelper'
has no applicable method named
'Partial' 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.
How would I achieve this with using the Razor view engine?
The RenderPartial does not return a string or IHtmlString value. But does the rendering by calling Write in the Response.
You could use the Partial extension, this returns an MvcHtmlString
#Html.Partial( ....
or
#{ Html.RenderPartial(....); }
If you really want RenderPartial
The compiler cannot choose the correct method because your Model is dynamic. Change the call to:
#Html.RenderPartial("~/Views/Inquiry/_InquiryList.cshtml", (List<string>)Model.InquiryList)
Or to whatever data type InquiryList is.
Remember to include your strongly typed #model directive in your new Razor view. It is an easy step to miss when converting views from .aspx to .cshtml. If you forget, that 'System.Web.Mvc.HtmlHelper' has no applicable method named 'Partial' error message could appear.
Related
I am new to asp.net core and am trying to render a partial view in an ASP.Net Core application. The address of the partial view is determined at run time. I have constructed a view model which is parsed into the view from the controller and contains the desired file address.
The following code throws the following compiler error:
#Html.Partial(Model.File);
Error CS1973 'IHtmlHelper' has no applicable method named 'Partial'
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.
Any help would be greatly appreciated.
The solution in the end was to specify the type in the Razor file. The following line worked:
#Html.Partial((string) Model.File)
Just to add to Lachlan Fergusson's excellent answer (thank you!) just to say that you also get this message if the name of your view contains a variable, without it's type.
So, the following line threw the error for me:
#Html.Partial("UserDetailsPartial." + language, Model)
...but it went away when I added this...
#Html.Partial("UserDetailsPartial." + (string)language, Model)
Behind the scenes, I had different partials based on language,
UserDetailsPartial.es.html
UserDetailsPartial.de.html
UserDetailsPartial.fr.html
The strange thing is that previously (with an earlier version of .Net Core?) the original line worked fine.
So, add this to Microsoft's "list of error messages which don't really explain what the problem is.."
In the following code of the example application of VS2015:
#model LoginViewModel
<p>
#Html.DisplayNameFor(m => m.Name)
</p>
I want to know how the compiler knows that m refers to the LoginViewModel if I never said that m is an alias for LoginViewModel.
And I would like help understanding the lambda expression of DisplayNameFor. Why it requires a lambda if we could just pass the string m.Name? How is it used here?
The given Razor template will be compiled, so the Razor view compiler can do some magic here.
The compiler knows the type of your model because of the #model directive (without the #model directive the compiler falls back to dynamic).
If you look at the #Html.DisplayNameFor directive, then the Html instance is an object of the type HtmlHelper<TModel> where TModel is the type given by the #model directive. In your case is the concrete type HtmlHelper<LoginViewModel>.
Now the HtmlHelper<LoginViewModel>.DisplayNameFor method is stongly typed and the compiler can figure that 'm' (which is only a parameter name) is of type LoginViewModel and that the lamdba expression returns a value from the model.
During runtime the DisplayNameFor method is executed by providing your model object as parameter 'm' the expression returns the object of the model member (or the object the expression returns) and the MVC framework can inspect the object (Type, Validation Attributes, etc.) and produces the appropriate html based on internal or custom templates.
If you would just pass a string, then MVC would not be able to get the needed type and validation annotations (and much more information).
Your first question: It passes LogonViewModel to #Html.DislplayNameFor method since you have define it on you first line as your model (#model LoginViewModel)
Aslo as it mentioned here:
What is the #Html.DisplayFor syntax for?
Html.DisplayFor() will render the DisplayTemplate that matches the
property's type.
If it can't find any, I suppose it invokes .ToString().
DisplayNameFor is a strongly typed HTML helper. These were first introduced in ASP.NET MVC 2. The purpose of them (as per the linked article) is to...
...provide a nice way to get better type-safety within your view templates. This enables better compile-time checking of your views (allowing you to find errors at build-time instead of at runtime), and also supports richer intellisense when editing your view templates within Visual Studio.
If you want to understand the innards of how they work, the source code is available on GitHub.
I know ViewBag is used in Razor view engine but not sure how to access viewBag's dynamic properties in aspx view engine.
As I want to put text inside Html.ValidationSummary() through Viewbag I am using the following syntax but getting error "has no applicable method named 'ValidationSummary' 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."
Syntex:
<%= Html.ValidationSummary(ViewBag.ValidationSummary)%>
It is complaining because ValidationSummary has no single parameter overload that takes a parameter of type dynamic; that is what ViewBag properties are. Cast the property to a string.
<%= Html.ValidationSummary((string)ViewBag.ValidationSummary)%>
Hi I'm trying to create a declarative Html helper method inside MVC partial page, everything works fine. But when I want to use built-in Html extension methods, I see there are no extension methods. Also I checked my view's webconfig file to add System.Web.Mvc.Html namespace. everything is OK, but I don't know why it's not working.
Any advice will be helpful.
Edit : Here is my code :
#using WebVoter.ViewModel
#using System.Web.Mvc.Html
#helper GetVoteList(IList<VoteQuestionViewModel> voteQuestionList)
{
<div class="head-panel">
#*For example ActionLink is not accessible here*#
#Html.ActionLink(....);
</div>
}
Inside Razor helpers you do not have reference to HtmlHelper. You need to pass it as parameter from the calling code:
#helper GetVoteList(HtmlHelper html, IList<VoteQuestionViewModel> voteQuestionList)
{
<div class="head-panel">
#html.ActionLink(....)
</div>
}
and when you want to call this helper from some view you need to pass the reference:
#GetVoteList(Html, ...)
Personally I've always preferred writing extension methods to the HtmlHelper class instead of using those inline Razor helpers. They would then be used as standard helpers:
#Html.GetVoteList(...)
The advantage is that you are no longer tied to Razor. Extension methods are view engine agnostic and make transition to other view engines less painful because they are C# code. Another benefit is that they can be unit tested.
There is a web.config under Views folder. Can you modify this config too?
I am trying to make a combination of a html helper and a Reder CSHTML.
In other words, how can I use a cshtml "template" with a html helper so I do not need to parse all the ugly HTML in the methods.
I am currently using #Html.Action but that is not preferable as it needs a working URL.
#Html.RenderAction("GetThreads", "Forum")
public ActionResult GetThreads()
{
return new EmptyResult();
}
This gives the exception:
Argument 1: cannot convert from 'void' to 'System.Web.WebPages.HelperResult
Do I always need to add a route in the Global.asax file? Or are there ways to call Actions without it (like HTML helpers, but with a template file).
I have been trying with RenderPartial, but I keep getting these errors: Argument 1: cannot convert from 'void' to 'System.Web.WebPages.HelperResult'
Surround it with #{}
#{Html.RenderPartial("_SomePartial");}
Use #Url.Action to get the URL of an action. I think that is what you need.
Or #Html.RenderPartial or #Html.RenderAction will spit out the view to the page.
EmptyResult won't render a view. That might be your problem.
You might be looking for RenderPartial.