This is a migrated thread and some comments may be shown as answers.

DropDownListFor Template Exception

1 Answer 206 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
Drewanz
Top achievements
Rank 1
Veteran
Drewanz asked on 21 Jul 2014, 10:50 PM
I have the following issue which may be something I've missed along the code.

One TemplateEditor for a ViewModel to produce a DropDownList with choices from a database:

@model MyApp.ViewModels.JobTitleViewModel
 
@(Html.Kendo().DropDownListFor(m => m)
.DataValueField("Id")
.DataTextField("Name")
.DataSource(r => r.Read("GetAll", "JobTitles"))
.HtmlAttributes(new { style = "width:90%" })
)

A controller action to return the current list of active items on the database:

[AllowAnonymous]
public JsonResult GetAll()
{
    var titles = context.JobTitles
        .Where(e => e.IsActive == true)
        .OrderBy(e => e.Name)
        .Select(t => new JobTitleViewModel
        {
            Id = t.Id,
            Name = t.Name,
            IsActive = t.IsActive
        });
     
    return this.Json(titles, JsonRequestBehavior.AllowGet);
}

Finally, a View where the user picks the desired option, and submit it back:

@model MyApp.Models.RegisterViewModel
@{
    ViewBag.Title = "Register";
}
 
<h2>@ViewBag.Title</h2>
 
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
     
    <div class="form-group">
        @Html.LabelFor(m => m.FullName, new { @class= "col-md-2 control-label"})
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.FullName, new { @class="form-control"})
        </div>
    </div>
 
    <div class="form-group">
        @Html.LabelFor(m => m.JobTitle.Name, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.EditorFor(m => m.JobTitle, new { @class = "form-control" })
        </div>
    </div>
 
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Registra" />
        </div>
    </div>
}
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


The editor is "hinted" using data annotation on the ViewModel :

public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }
 
    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }
 
    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
 
    [StringLength(80, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 4)]
    [Display(Name = "Name")]
    public string FullName { get; set; }
 
    [UIHint("JobTitleEditor")]
    public JobTitleViewModel JobTitle { get; set; }
}


When the View is submitted back, the ModelState is not valid with an error associated with the JobTitle property, resulting in an exception with the following text:

The parameter conversion from type 'System.String' to type 'MyApp.ViewModels.JobTitleViewModel' failed because no type converter can convert between these types.

Could you please point what am I doing wrong ??

Regards.

1 Answer, 1 is accepted

Sort by
0
Accepted
Georgi Krustev
Telerik team
answered on 23 Jul 2014, 01:42 PM
Hello Marcello,

We answered to the support ticket opened on the same subject. I will ask you to continue our discussion in only one thread to avoid any duplication. Thank you for the understanding.

Here is a quote of the answer:

The problem comes from the difference between what the DefaultModelBinder expects and what is send from the client (using Form element). In general, ASP.NET MVC requires "ObjectFieldName.PropertyName" format when it comes to complex objects binding. The DropDownList widget uses input element under the hood and that is why only the selected value is send back to the server and not the whole object. When it comes to form posting the dropdownlist declaration:
Copy Code
@(Html.Kendo().DropDownListFor(m => m)
...
)
is absolutely equivalent to:
Copy Code
@model MyApp.ViewModels.JobTitleViewModel
  
@(Html.TextBoxFor(m => m))

If you would like to avoid the error, then you will need to set the widgte name to JobTitleViewModel.Id.Thus the model binder will be able to map the value correctly. Once this is done, you can find the whole JobTitleViewModel based on the selected value and set the RegisterViewModel.JobTitle property.

Regards,
Georgi Krustev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
DropDownList
Asked by
Drewanz
Top achievements
Rank 1
Veteran
Answers by
Georgi Krustev
Telerik team
Share this question
or