I'm working on a MVC3 web application. I want a list of rotation shown in view. But during build I get error:
Error 2971 'System.Web.Mvc.SelectList' does not contain a definition
for 'MakeSelection' and no extension method 'MakeSelection' accepting
a first argument of type 'System.Web.Mvc.SelectList' could be found
(are you missing a using directive or an assembly reference?).
My code in view:
<div class="editor-field">
#Html.DropDownListFor(model => model.JobFiles[i].JobPages[j].UserRotation, (ViewData["rotation"] as SelectList).MakeSelection(Model.JobFiles[i].JobPages[j].UserRotation))
</div>
Please help. Thx in advance.
You error is telling you that the MakeSelection function does not belong to the System.Web.Mvc.SelectList object. I did find this extension method -
public static SelectList MakeSelection(this SelectList list, object selection)
{
return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection);
}
in this question, are you missing the extension method from your code?
Related
I have this code line in my MVC 4 application which was converted from MVC 3:
#Html.HiddenFor(model => model.IsInhouse) // IsInhoue is bool
This worked fine when application is MVC 3 but now it's malfunctioning.
I tried displaying the value using #Html.LabelFor(model => model.IsInhouse) and it displays as 'IsInhouse', not saying the content value.
Any clue on this issue is appriciated. I'm new to MVC.
EDIT: Replacing #Html.HiddenFor with <input type="hidden" name="IsInhouse" value="#Html.AttributeEncode(Model.IsInhouse)" id="IsInhouse" /> solved the issue.
LabelFor would display its Property Name, that's its purpose. To get its value, use EditorFor
I have a model for a drop down menu similar to this one. I am trying to create a controller for it.
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View(new MyData());
}
And I create my View like this
#Html.DropDownListFor(m => m.State,
new SelectList(Model.StateList, "Value", "Text"))
But I am receiving the error below for the line above:
Compiler Error Message: CS1061: 'System.Collections.Generic.List<Projects.Models.MyData>' does not contain a definition for 'StateList' and no extension method 'StateList' accepting a first argument of type 'System.Collections.Generic.List<Projects.Models.MyData>' could be found (are you missing a using directive or an assembly reference?)
Can you please direct me what I am doing wrong?
the problem is #model List<ProjectName.Models.MyData>
simply change it to
#model Projects.Models.MyData
cheers!
I have a situation where I want to use a custom EditorTemplate with a ViewModel. So I have my ViewModel...
class Aspect {
}
class AspectViewModel {
}
then my EditorTemplate
Views
Shared
EditorTemplates
Aspect.cshtml
Aspect.cshtml
#model AspectViewModel
// other html
Then in another view that takes AspectViewModel, I call #Html.EditorFor(model => model), but it does not work. It only works if I use a hard-coded string #Html.EditorForModel("Aspect").
Any idea why it isn't being called?
You should name the editor template AspectViewModel.cshtml if it is strongly typed to AspectViewModel. Then all you have to do is:
#model AspectViewModel
#Html.EditorForModel()
or
#model SomeViewModel
#Html.EditorFor(x => x.Aspect)
where the Aspect property of SomeViewModel is of type AspectViewModel.
The convention is that the editor/display should be named as the type of the property you are calling it on and not the name of this property.
They also work greatly with collections. For example if you have the following property:
public class SomeViewModel
{
public IEnumerable<AspectViewModel> Aspects { get; set; }
}
and you use:
#model SomeViewModel
#Html.EditorFor(x => x.Aspects)
then the ~/Views/Shared/EditorTemplates/AspectViewModel.cshtml editor template wil be rendered for each element of this collection. Thanks to this you really no longer need to ever write for/foreach loops in your views.
This is because your model is AspectViewModel, but your view name is Aspect. They must match exactly.
I'm new to MVC, so I wasn't sure what the best approach would be here.
I have a view model that contains several collections like this:
public class MainViewModel{
public List<AViewModel> A { get; set; }
public List<BViewModel> B {get; set; }
...}
I'm using Steve Sanderson's approach here to dynamically add items to a collection, and it's working fine as long as the child items are editable on the main view.
The problem I'm having is returning a read only list with an edit link that will open the details to edit in a popup dialog.
Since these items may be newly added, I can't use the ID property to return a partial view from the controller. It seems like I'll have to render the editors in a hidden div like this:
<div class="AEditorRow">
#using (Html.BeginCollectionItem("A"))
{
#Html.DisplayFor(l => l.ID)
#Html.DisplayFor(l => l.Name)
#Html.DisplayFor(l => l.Code)
edit <text>|</text>
delete
<div class="ADetails" style="display: none">
#using (Html.BeginForm("EditA", "Controller"))
{<fieldset>
<legend>Location</legend>
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.Code)
</div>
Does anyone know of a better way to do this?
After working on this issue for a while now I was able to find a walk-through that worked for me.
http://jarrettmeyer.com/post/2995732471/nested-collection-models-in-asp-net-mvc-3
I think this is the most applicable technique for accomplishing dynamically added nested collection objects for MVC3. Most of the other suggestions I've found were meant for MVC2 or MVC1, and it seems that every iteration of MVC the best way to accomplish this changes slightly.
Hopefully this works for you.
I have the same question. Now looking for solution.
Seems like this resources can help:
http://www.joe-stevens.com/2011/06/06/editing-and-binding-nested-lists-with-asp-net-mvc-2/
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
Model binding nested collections in ASP.NET MVC
This code was converted from some ASP.Net MVC 2 code in this tutorial:
MVC 2 Editor Template with DateTime
It is a custom EditorTemplate for DateTime fields stored as 'EditorTemplates/DateTime.cshtml'.
#Model DateTime?
#Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { #class = "datePicker" })
However I get the following error when using #Html.EditorFor(model => model.NewAbsence.StartDate):
CS1973: 'System.Web.Mvc.HtmlHelper' has no applicable method named 'TextBox' 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've seen some similar posts on here which mention casting the parameter of the EditorFor method, however I cannot seem to get this to work in my example.
Could someone please point out what I will need to change in my code. Thanks.
Actually it's #model with lowercase m:
#model DateTime?
^
instead of:
#Model DateTime?
So to sort of summarize what people are saying, and make it a bit more generic. If your view is declaring that it accepts dynamic models:
#model dynamic
Then things like extension methods will not be able to infer the types of arguments passed to them. Here are two examples (using Razor because it's awesome):
#Html.TextBox("myTextBoxName", Model.MyTextBoxValue)
#Html.DropDownList("myDropDownName", Model.MySelectList))
In these cases, the engine doesn't know what types Model.MyTextBoxValue or Model.MySelectList are, therefore it can't figure out what overloads of the extension methods to compile. So you just help it along with some strong typing:
#Html.TextBox("myTextBoxName", (string)Model.MyTextBoxValue)
#Html.DropDownList("myDropDownName", (SelectList)Model.MySelectList))
By the way, just to stop people from potentially pulling out their hair, that SelectList has to be properly instantiated with something like:
var items = List<SelectListItem>();
...
new SelectList(items, "Value", "Text");
As a temporary work around I am using:
<div class="editor-field date-field">
#Html.EditorFor(model => model.NewAbsence.StartDate)
#Html.ValidationMessageFor(model => model.NewAbsence.StartDate)
</div>
Then using the jQuery selector:
$(".date-field > input").datepicker({
showOn: "button",
buttonImage: "*pathtoimage*"
});
To apply the date picker to the input tags within the 'date-field' div. However this still doesn't format the date value how I want it to display initially, and cuts out the editor template entirely.
The error message comes from your textbox statement. In a template, this becomes a dynamic expression, and .Net doesn't know how to type the Model properties.
#Html.TextBox("", (string)(Model==null ? Model.Value.ToShortDateString() : string.Empty), new { style = "width: 10em;", #class="datefield" })
Explicitly cast your date value as string, and the dynamic expression has the information it needs. I also had a problem with the .HasValue property, but that wasn't the point of your question.