我有一个包含BlogPost和Tag实体的模型。
public class Tag
{
public string Name { get; set; }
public string Slug { get; set; }
}
public class BlogPost : ITaggable
{
public BlogPost()
{
this.Tags = new List<Tag>();
}
public ICollection<Tag> Tags { get; set; }
[AllowHtml]
public string Text { get; set; }
}
在管理员BlogPost编辑页面标签应该用一个文本输入表示,用逗号分隔。非常像StackOverflow标签的输入。
这意味着将ICollection序列化为字符串,并将deseralization返回到集合。 我很满意默认模型绑定器,除了BlogPost的Tags集合。
我知道处理它的选项很少:
自定义模型Binder - 需要覆盖所有BlogPost绑定 - 在真正的BlogPost实体中确实有很多属性。
创建与BlogPost模型无关的文本输入,并使用Form参数获取/设置其值。它也需要更多的手工工作。
还有别的......
您如何为博客帖子实现标签输入?
更新
现在我试试这个:
public List<Tag> Tags { get; set; }
public string TagsString {
get
{
var tags = Tags.Select(tg => tg.Name).ToArray();
var res = string.Join(",", tags);
return res;
}
set
{
var tags = value.Split(',');
Tags = new List<Tag>();
foreach (var tag in tags)
Tags.Add(new Tag { Name = tag });
}
}
答案 0 :(得分:4)
这是在您的视图和模型之间引入ViewModel
的完美案例。
ViewModel
将允许您修改特定视图的数据表示(将其拆分为字符串)(这是在每个视图中创建一个视图的最佳做法),而不会改变模型的完整性。< / p>
然后,您的控制器将负责序列化/反序列化。
以下是一些文章,讨论了ASP.NET MVC应用程序中ViewModel的需求和方式:
答案 1 :(得分:1)
我会维护UI / UX,以便在单个文本框中显示逗号分隔。
至于将它们作为控制器中的集合,我个人会坚持使用默认的模型绑定器,但这并不一定意味着它是正确的方式。
我会做类似于#2的事情,但我会使用<select multiple="multiple">
,因此每个标记都有1个<option selected="selected">TagName/Slug</option>
元素。
至于维护文本框和多选列表之间的依赖关系/绑定,我会使用knockoutjs。解析文本框中的逗号,并更新(隐藏)多选。提交给控制器时,忽略文本框(或者只是不要将其作为服务器端视图模型的一部分)。