简体   繁体   中英

C# & ASP.NET MVC Issues with View model and List

I am having some issues that i cannot seem to figure out. What I am attempting to do is produce a list of records with a checkbox to select the record. The first issue i had was adding the checkbox to the model. It was telling me that it was an invalid column. So I created a view model with the added checkbox.

I get this error:

Cannot implicitly convert type 'System.Collections.GenericList' to System.Collections.Generic.List'

Here is the Controller GET:

public ActionResult SelectTags()
{
    TagsModel tags = new TagsModel();
    using (ProjectEntities db = new ProjectEntities())
    {
        tags.Tags = db.Tags.ToList<Tags>();
    }
    return View(tags);
}

Then on the Post I am getting:

'IEnumerable<TagsViewModel>' does not contain a definition for 'ToList' and the best extention method overload 'Enumerable.ToList<tags>(IEnumerable<Tags>)' requires a reciever of type 'IEnumerable<Tags>'

Here is the POST:

[HttpPost]
public ActionResult SelectTags(TagsModel model)
{
    var selectedTags = model.Tags.Where(x => x.IsChecked == true).ToList<Tags>();

    return Content(String.Join(",",selectedTags.Select(x => x.TagsId)));
}

I am using System.Link on the page.

Here are my Models:

namespace Project.ProjectModels.Entities
{
    public class Tags
    {
      [Key]
      public int TagsId { get; set; }

      [Display(Name = "Id")]
      public string Id { get; set; }

      [Display(Name = "Address")]
      public string DataHmiAddress { get; set; }

      [Display(Name = "Type")]
      public string DataHmiDataType { get; set; }

      [Display(Name = "Round Places")]
      public int DataHmiRoundPlaces { get; set; }

      [Display(Name = "Update In")]
      public int DataHmiUpdateIn { get; set; }

      [Display(Name = "Update Level")]
      public int DataHmiUpdateLevel { get; set; }

      [Display(Name = "Value")]
      [DisplayFormat(DataFormatString = "{0:0.000}", ApplyFormatInEditMode = true)]
      public decimal DataHmiValue { get; set; }

    }
}


namespace Project.ViewModels
{
    public class TagsViewModel
    {
      public int TagsId { get; set; }

      [Display(Name = "Id")]
      public string Id { get; set; }

      [Display(Name = "Address")]
      public string DataHmiAddress { get; set; }

      [Display(Name = "Type")]
      public string DataHmiDataType { get; set; }

      [Display(Name = "Round Places")]
      public int DataHmiRoundPlaces { get; set; }

      [Display(Name = "Update In")]
      public int DataHmiUpdateIn { get; set; }

      [Display(Name = "Update Level")]
      public int DataHmiUpdateLevel { get; set; }

      [Display(Name = "Value")]
      [DisplayFormat(DataFormatString = "{0:0.000}", ApplyFormatInEditMode = true)]
      public decimal DataHmiValue { get; set; }

      public bool IsChecked { get; set; }
  }

  public class TagsModel
  {
    public virtual List<TagsViewModel> Tags { get; set; }
  }
}

Thanks for your help!

You cannot initialize a list of TagsViewModel with a list of Tags . There is no implicit conversion between the two lists and not an implicit conversion between a Tags and a TagsViewModel.

You need to implement yourself this conversion.
One possibility is through the implicit operator keyword

For example, you could add this code to the Tags class:

public static implicit operator TagsViewModel(Tags source)
{
    if (source == null) return null;
    TagsViewModel model = new TagsViewModel();
    model.Id = source.Id;
    .... set the other properties here...
    return model;
}

Now we have instructed the Tags class how to convert itself to a TagsViewModel .
At this point the code that assigns the List<TagsViewModel> could be changed to:

public ActionResult SelectTags()
{
    TagsModel tags = new TagsModel();
    using (ProjectEntities db = new ProjectEntities())
    {
        foreach(var t in db.Tags)
           // At this point the Tags t variable will be 
           // converted to a TagsViewModel and added to the list
           tags.Tags.Add(t);
    }
    return View(tags);
}

Do not forget to initialize the Tags property inside the tags variable.
Change the TagsModel class to

public class TagsModel
{
    public virtual List<TagsViewModel> Tags { get; set; } = new List<TagsViewModel>();
}

For the POST part you do the inverse. Add the implicit conversion to the TagsViewModel class

public static implicit operator Tags(TagsViewModel source)
{
    if (source == null) return null;
    Tags model = new Tags();
    model.Id = source.Id;
    .... set the other properties here...
    return model;
}

And use a foreach loop to build the SelectedTags list

[HttpPost]
public ActionResult SelectTags(TagsModel model)
{
    List<Tags> selectedTags = new List<Tags>();
    foreach(var t in model.Tags.Where(x => x.IsChecked))
       selectedTags.Add(t);

    return Content(String.Join(",",selectedTags.Select(x => x.TagsId)));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM