Saqib Vaid
Saqib Vaid

Reputation: 412

ModelState is Invalid for Drop Down List

I have a parent table called "Language" which stores the language skills of a person (like he is fluent, good, ok...)

I have a child table "Manpower" with 2 foreign keys pointing to the same table for different languages (English & Arabic).

Now when I try to create a new manpower resource it always return ModelState is invalid for the language.

Error is "The parameter conversion from type 'System.String' to type 'AlTmaizMVC3.Models.Language' failed because no type converter can convert between these types."

Controller :

   [Authorize]        
    public ActionResult Create()
    {
        ViewBag.CategoryId = new SelectList(db.Categories.OrderBy(r => r.Name), "Id", "Name");
        ViewBag.CountryId = new SelectList(db.Countries.OrderBy(r => r.Name), "Id", "Name");
        ViewBag.MaritalStatusId = new SelectList(db.MaritalStatus.OrderBy(r => r.Name), "Id", "Name");
        ViewBag.ReligionId = new SelectList(db.Religions.OrderBy(r => r.Name), "Id", "Name");
        ViewBag.EnglishID = new SelectList(db.Languages , "Id", "Name");
        ViewBag.ArabicID = new SelectList(db.Languages, "Id", "Name");
        return View("~/Views/en/Create.cshtml");
    } 

    [HttpPost]
    [Authorize]
    public ActionResult Create(Manpower manpower)
    {
        if (ModelState.IsValid)
        {
            manpower.CreatedBy = User.Identity.Name;
            manpower.CreatedOn = DateTime.Now;
            db.Manpowers.AddObject(manpower);
            db.SaveChanges();
            return RedirectToAction("AddImage", new { manpower.Id});  
        }

        ViewBag.CategoryId = new SelectList(db.Categories.OrderBy(r => r.Name), "Id", "Name", manpower.CategoryId);
        ViewBag.CountryId = new SelectList(db.Countries.OrderBy(r => r.Name), "Id", "Name", manpower.CountryId);
        ViewBag.MaritalStatusId = new SelectList(db.MaritalStatus.OrderBy(r => r.Name), "Id", "Name", manpower.MaritalStatusId);
        ViewBag.ReligionId = new SelectList(db.Religions.OrderBy(r => r.Name), "Id", "Name", manpower.ReligionId);
        ViewBag.EnglishID = new SelectList(db.Languages, "Id", "Name", manpower.EnglishID);
        ViewBag.ArabicID = new SelectList(db.Languages, "Id", "Name", manpower.ArabicID);
        return View("~/Views/en/Create.cshtml", manpower);
    }

View

   <tr>
            <td>@Html.LabelFor(model => model.MaritalStatusId, "Marital Status")</td>
            <td>:</td>
            <td>@Html.DropDownList("MaritalStatusId", String.Empty)<br />
                @Html.ValidationMessageFor(model => model.MaritalStatusId)</td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>@Html.LabelFor(model => model.EnglishID, "English")</td>
            <td>:</td>
            <td>@Html.DropDownList("EnglishID", String.Empty)<br />                    
                @Html.ValidationMessageFor(model => model.EnglishID)</td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>@Html.LabelFor(model => model.ArabicID, "Arabic")</td>
            <td>:</td>
            <td>@Html.DropDownList("ArabicID", String.Empty)<br />
                @Html.ValidationMessageFor(model => model.ArabicID)</td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>

Model for Language table

[EdmEntityTypeAttribute(NamespaceName="AlTmaizDBModel", Name="Language")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Language : EntityObject
{
    #region Factory Method

    /// <summary>
    /// Create a new Language object.
    /// </summary>
    /// <param name="id">Initial value of the Id property.</param>
    public static Language CreateLanguage(global::System.Int16 id)
    {
        Language language = new Language();
        language.Id = id;
        return language;
    }

    #endregion
    #region Primitive Properties

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.Int16 Id
    {
        get
        {
            return _Id;
        }
        set
        {
            if (_Id != value)
            {
                OnIdChanging(value);
                ReportPropertyChanging("Id");
                _Id = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("Id");
                OnIdChanged();
            }
        }
    }
    private global::System.Int16 _Id;
    partial void OnIdChanging(global::System.Int16 value);
    partial void OnIdChanged();

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
    [DataMemberAttribute()]
    public global::System.String Name
    {
        get
        {
            return _Name;
        }
        set
        {
            OnNameChanging(value);
            ReportPropertyChanging("Name");
            _Name = StructuralObject.SetValidValue(value, true);
            ReportPropertyChanged("Name");
            OnNameChanged();
        }
    }
    private global::System.String _Name;
    partial void OnNameChanging(global::System.String value);
    partial void OnNameChanged();

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
    [DataMemberAttribute()]
    public global::System.String NameAR
    {
        get
        {
            return _NameAR;
        }
        set
        {
            OnNameARChanging(value);
            ReportPropertyChanging("NameAR");
            _NameAR = StructuralObject.SetValidValue(value, true);
            ReportPropertyChanged("NameAR");
            OnNameARChanged();
        }
    }
    private global::System.String _NameAR;
    partial void OnNameARChanging(global::System.String value);
    partial void OnNameARChanged();

    #endregion

    #region Navigation Properties

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [XmlIgnoreAttribute()]
    [SoapIgnoreAttribute()]
    [DataMemberAttribute()]
    [EdmRelationshipNavigationPropertyAttribute("AlTmaizDBModel", "FK_Manpower_Language", "Manpower")]
    public EntityCollection<Manpower> Manpowers
    {
        get
        {
            return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Manpower>("AlTmaizDBModel.FK_Manpower_Language", "Manpower");
        }
        set
        {
            if ((value != null))
            {
                ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Manpower>("AlTmaizDBModel.FK_Manpower_Language", "Manpower", value);
            }
        }
    }

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [XmlIgnoreAttribute()]
    [SoapIgnoreAttribute()]
    [DataMemberAttribute()]
    [EdmRelationshipNavigationPropertyAttribute("AlTmaizDBModel", "FK_Manpower_Language1", "Manpower")]
    public EntityCollection<Manpower> Manpowers1
    {
        get
        {
            return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Manpower>("AlTmaizDBModel.FK_Manpower_Language1", "Manpower");
        }
        set
        {
            if ((value != null))
            {
                ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Manpower>("AlTmaizDBModel.FK_Manpower_Language1", "Manpower", value);
            }
        }
    }

    #endregion
}

Please help. Thanks

Upvotes: 0

Views: 2330

Answers (1)

Mathew Thompson
Mathew Thompson

Reputation: 56429

You should be using a Model, not the ViewBag, that's where your headache starts!

First let's create a model based on what you need:

public class MyModel
{
    public Manpower Manpower { get; set; }

    public SelectList Categories { get; set; }
    public SelectList MaritalStatuses { get; set; }
    public SelectList Religions { get; set; }
    public SelectList Languages { get; set; }

    //here's your Load Method to populate it
    public MyModel Load()
    {
        //load your Manpower object here
        Categories = new SelectList(db.Categories
            .OrderBy(x => x.Name)
            .ToList(), "Id", "Name");
        Countries = new SelectList(db.Countries
            .OrderBy(x => x.Name)
            .ToList(), "Id", "Name");
        MaritalStatuses = new SelectList(db.MaritalStatus
            .OrderBy(x => x.Name)
            .ToList(), "Id", "Name");
        Religions = new SelectList(db.Religions
            .OrderBy(x => x.Name)
            .ToList(), "Id", "Name");
        Languages = .new SelectList(db.Languages
            .OrderBy(x => x.Name)
            .ToList(), "Id", "Name");
    }
}

Now let's fix that get controller method:

[Authorize]        
public ActionResult Create()
{
    var model = new MyModel().Load();

    return View("~/Views/en/Create.cshtml", model);
} 

Next, I'll show you sample view Code (format it appropriately), note that I'm assuming here that Manpower has all the possible fields:

@model MyModel //make sure this is the top line of your view

@Html.DropDownListFor(m => m.Manpower.CategoryId, m.Categories)
@Html.DropDownListFor(m => m.Manpower.MaritalStatusId, m.MaritalStatuses)
@Html.DropDownListFor(m => m.Manpower.ReligionId, m.Religions)
@Html.DropDownListFor(m => m.Manpower.EnglishId, m.Languages)
@Html.DropDownListFor(m => m.Manpower.ArabicId, m.Languages)

//your other Manpower object items here now....

Now in the Save method we can do:

[HttpPost]
[Authorize]
public ActionResult Create(MyModel model)
{
    if (ModelState.IsValid)
    {
        model.Manpower.CreatedBy = User.Identity.Name;
        model.Manpower.CreatedOn = DateTime.Now;
        db.Manpowers.AddObject(model.Manpower);
        db.SaveChanges();
        return RedirectToAction("AddImage", new { manpower.Id});  
    }

    return RedirectToAction("Create"); //not sure why you're going back to create though?
}

Upvotes: 4

Related Questions