ASP.NET MVC 3:博客文章模型标签绑定最佳实践
我有一个包含 BlogPost 和标签实体的模型。
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 序列化为字符串,然后反序列化回集合。 除了 BlogPost 的标签集合之外,我对默认模型活页夹很满意。
我知道处理它的选项很少:
自定义模型绑定器 - 需要覆盖所有 BlogPost 绑定 - 真正的 BlogPost 实体中有很多属性。
创建与 BlogPost 模型无关的文本输入,并使用表单参数获取/设置其值。它还需要更多的手动工作。
其他......
您将如何实现博客文章的标签输入?
更新:
现在我尝试这样做:
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 });
}
}
I have a model with BlogPost and Tag entities.
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; }
}
On admin BlogPost edit page tags should be represented in one text input, separated by comma. Pretty much like StackOverflow tag's input.
It means serialization of ICollection to a string, and deseralization back to a collection.
I'm happy with default model binder, beside the Tags collection of BlogPost.
There are few options I know to handle it:
Custom Model Binder - with a need to override all BlogPost bindings - there are really a lot properties in a real BlogPost entity.
Create a text input not related to a BlogPost model, and get/set it's values using Form parameters. It requires more manual work too.
Something else....
How would you implement tags input for a blog post?
UPDATE:
For now I try this:
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 });
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是在视图和模型之间引入
ViewModel
的完美案例。ViewModel
将允许您修改特定视图的数据表示(将它们拆分为字符串)(最佳实践是为每个视图创建一个视图),而不会改变模型的完整性。然后,您的控制器将负责序列化/反序列化。
以下是一些讨论 ASP.NET MVC 应用程序中 ViewModel 的需求以及如何使用的文章:
This is the perfect case to introduce a
ViewModel
between your view and your model.A
ViewModel
will allow you to modify the representation of your data (split them in a string) for a specific view (it's a best practice to create one per view) without altering the integrity of your model.Then, your controller will be in charge of the serialization/deserialization.
Here are a few articles talking about the need and the how of ViewModels in ASP.NET MVC applications:
我会维护 UI/UX 以在单个文本框中显示逗号分隔的内容。
至于将它们作为控制器中的集合,我个人会坚持使用默认的模型绑定器,但这并不一定意味着这是正确的方法。
我会做类似于你的#2的事情,但是我会使用
至于维护文本框和多选列表之间的依赖/绑定,我将使用 knockoutjs 。解析文本框中的逗号,并更新(隐藏的)多选。当提交到控制器时,忽略文本框(或者只是不将其作为服务器端视图模型的一部分)。
I would maintain the UI/UX to show them comma separated in a single text box.
As far as getting them as a collection in the controller, I personally would stick with the default modelbinder, but that doesn't necessarily mean it's the correct way.
I would do something akin to your #2, however I would use a
<select multiple="multiple">
so that there was 1<option selected="selected">TagName/Slug</option>
element for each tag.As for maintaining the dependency / binding between the text box and the multi-select list, I would use knockoutjs for this. Parse the commas in the text box, and update the (hidden) multi-select. When submitted to the controller, ignore the text box (or just don't make it part of your server-side viewmodel).