3

我有两个模型,一个代码模型和一个标签模型,它们通过多对多关系链接。我正在尝试添加一个代码条目,其中包括使用视图模型可能选择的许多标签(在我的视图中使用标签的复选框)。我收到错误消息:

传入字典的模型项的类型为“System.Collections.Generic.List'1[StoRed.Models.Code]”,但此字典需要类型为“System.Collections.Generic.IEnumerable`1[StoRed”的模型项.Models.CodeTagViewModel]'。

感觉就像我需要以某种方式将我的数据转换为可接受的格式,然后再尝试将其保存到表中,但我是 MVC 新手,我无法在互联网上找到任何关于我的特定问题的有用信息。任何帮助将不胜感激。

代码模型

public class Code
{
    [Key]
    public int CodeID { get; set; }

    [Required]
    [StringLength(30)]
    public string Title { get; set; }

    [Required]
    [StringLength(150)]
    public string Description { get; set; }

    public DateTime DateAdded { get; set; }

    public DateTime LastUpdated { get; set; }

    [Required]
    [StringLength(30)]
    public string Project { get; set; }

    [Required]
    [StringLength(30)]
    public string CMS { get; set; }

    public int DotNetVersion { get; set; }

    [Required]
    [StringLength(150)]
    public string Dependencies { get; set; }

    [StringLength(30)]
    public string Author { get; set; }

    public string CodeFile { get; set; }

    [Required]
    [StringLength(100)]
    public string TFSLocation { get; set; }

    ////Creates a relationship in the DB with Tag
    //[ForeignKey("TagID")]
    public virtual ICollection<Tag> Tags { get; set; }

    ////Purely for API
    //[Required]
    public int TagID { get; set; }
}

标签模型

public class Tag
{
    [Key]
    public int TagID { get; set; }

    [Required]
    [StringLength(30)]
    public string TagName { get; set; }

    public virtual ICollection<Code> Code { get; set; }
}

上下文

public class Context : DbContext
{
    public DbSet<Code> Code { get; set; }

    public DbSet<Tag> Tags { get; set; }
}

视图模型

public class CodeTagViewModel
{
    public Tag Tag { get; set; }
    public Tag TagID { get; set; }
    public List<Tag> Tags { get; set; }


    public int CodeID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime DateAdded { get; set; }
    public DateTime LastUpdated { get; set; }
    public string Project { get; set; }
    public string CMS { get; set; }
    public int DotNetVersion { get; set; }
    public string Dependencies { get; set; }
    public string Author { get; set; }
    public string CodeFile { get; set; }
    public string TFSLocation { get; set; }
}

代码控制器的相关部分

    [HttpPost]
    public ActionResult Create(CodeTagViewModel codeTagViewModel)
    {
        if (ModelState.IsValid)
        {
            Code code = new Code();
            Tag tag = new Tag();

            var codeTag = new CodeTagViewModel();

            code.Title = codeTagViewModel.Title;
            code.Description = codeTagViewModel.Description;
            code.DateAdded = codeTagViewModel.DateAdded;
            code.LastUpdated = codeTagViewModel.LastUpdated;
            code.Project = codeTagViewModel.Project;
            code.CMS = codeTagViewModel.CMS;
            code.DotNetVersion = codeTagViewModel.DotNetVersion;
            code.Dependencies = codeTagViewModel.Dependencies;
            code.Author = codeTagViewModel.Author;
            code.CodeFile = codeTagViewModel.CodeFile;
            code.TFSLocation = codeTagViewModel.TFSLocation;
            code.Tags = codeTagViewModel.Tags;

            db.Code.Add(code);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(codeTagViewModel);
    }
4

1 回答 1

3

你最好的选择是创建某种提供者/经理/服务/工厂/处理程序 - 选择一个最有意义的名称,它在通过系统的数据流中所做的工作 - 负责获取 ViewModel并将 ViewModel 的属性映射到域模型的实例中,然后将域模型本身或通过将水合域模型传递到存储库层来将域模型持久化到数据存储中。您可以手动执行此操作,也可以使用 AutoMapper 之类的工具执行此操作。这是一个快速的手动示例:

CommandHandlers使用接口和依赖处理程序在您的 Web 项目中创建一个文件夹:

public interface ICodeCommandHandler
{
    int Save(CodeTagViewModel input);
}

public class CodeCommandHandler : ICodeCommandHandler
{
    private IRepository<Code> repository;

    public CodeCommandHandler(IRepository<Code> repository)
    {
        this.repository = repository;
    }

    public int Save(CodeTagViewModel input)
    {
        Code code = new Code();
        Tag tag = new Tag();
        code.Title = input.Title;
        code.Description = input.Description;
        code.DateAdded = input.DateAdded;
        code.LastUpdated = input.LastUpdated;
        code.Project = input.Project;
        code.CMS = input.CMS;
        code.DotNetVersion = input.DotNetVersion;
        code.Dependencies = input.Dependencies;
        code.Author = input.Author;
        code.CodeFile = input.CodeFile;
        code.TFSLocation = input.TFSLocation;
        code.Tags.Add(tag);

        return repository.Save(code);

    }
}

然后在您的控制器中,通过构造函数注入将 ICodeCommandHandler 注入,就像您对以下存储库所做的那样CodeCommandHandler

private readonly ICodeCommandHandler commandHandler;

public CodeController(ICodeCommandHandler commandHandler)
{
    this.commandHandler = commandHandler;
}

[HttpPost]
public ActionResult Create(CodeTagViewModel codeTagViewModel)
{
    if (!ModelState.IsValid)
    {
        return View(codeTagViewModel);
    }

    var id = codeCommandHandler.Save(codeTagViewModel);
    // maybe do something useful with the document id after save
    return RedirectToAction("Index");  
}

为了保持Repository美观和简单,下面是它的外观:

public interface IRepository<T>
{
    int Save(T entity);
}

public class CodeRepository : IRepository<Code>
{
    public int Save(Code entity)
    {
        using (var context = new Context())
        {
            context.Code.Add(entity);
            context.SaveChanges();
        }
    }
}

我没有详细介绍依赖注入方面的事情,因为这不是问题的一部分,但这应该让你知道从哪里开始

于 2013-01-10T10:32:06.837 回答