Sha*_*eKm 4 asp.net-mvc wysiwyg template-engine content-management-system
我需要一个简单的功能来在这些页面上添加页面/更改内容.我已经看过n2和其他预构建的CMS工具,但这些是我需要的简单CMS功能的高级方法.
什么是最好的方法?我已经有一个MVC应用程序,我想添加/构建一个简单的功能,如:
不知道从哪里开始.
任何信息非常感谢.谢谢
这适用于.NET MVC
And*_*tad 10
假设你正在使用ASP.NET MVC而你想保持简单,那么这样的事情如何:
public abstract class TemplateBase
{
public abstract string TemplateName { get; }
}
public class SingleColumnTemplate : TemplateBase
{
public override string TemplateName { get { return "Single-column page"; } }
public AreaContainer CenterColumn { get; protected set; }
public SingleColumnTemplate()
{
CenterColumn = new AreaContainer("Center column");
}
}
public class TwoColumnTemplate : TemplateBase
{
public override string TemplateName { get { return "Two-column page"; } }
public AreaContainer LeftColumn { get; protected set; }
public AreaContainer RightColumn { get; protected set; }
public TwoColumnTemplate()
{
LeftColumn = new AreaContainer("Left column");
RightColumn = new AreaContainer("Right column");
}
}
// TODO Add more template types
public class AreaContainer
{
public string ContainerName { get; set; }
public IList<AreaBase> Areas { get; protected set; }
public AreaContainer(string name)
{
ContainerName = name;
Areas = new List<AreaBase>();
}
}
public abstract class AreaBase
{
public abstract string AreaName { get; }
}
public class HtmlArea : AreaBase
{
public override string AreaName { get { return "HTML content"; } }
public string HtmlContent { get; set; }
}
// TODO Add more area types
public class Page
{
public int Id { get; set; }
public string Title { get; set; }
public TemplateBase Template { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
用于编辑现有页面的控制器操作可能类似于:
public class PageAdminController : Controller
{
[HttpGet]
ActionResult Edit(int id)
{
var page = GetPageFromStorageById(id);
// TODO If the page is not found, issue 404
return View(page);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
在Views/PageAdmin/Edit.aspx应该强类型化的view()中,只要为每个模板类型创建了局部视图ViewPage<Page>,就可以使用该HtmlHelper.EditorFor(...)方法呈现相应的模板视图:
<!-- Inside the edit view for Page (Edit.aspx) -->
<%: Html.HiddenFor(m => m.Id) %>
<%: Html.EditorFor(m => m.Title) %>
<%: Html.EditorFor(m => m.Template) %>
Run Code Online (Sandbox Code Playgroud)
在该文件夹Views/PageAdmin/EditorTemplates,你会然后把每个模板和区域类型的部分编辑的观点(即SingleColumnTemplate.ascx,TwoColumnTemplate.ascx和HtmlArea.ascx).您可能还想为其创建局部视图AreaContainer.
至于接收编辑过的页面的控制器动作,事情会变得复杂一些.由于Page具有类型的属性TemplateBase,这是一个抽象类,因此DefaultModelBinder不知道如何填充它.您可以通过编写自定义模型绑定器来解决这个问题,该绑定器以某种方式"知道"要实例化的实现类.怎么会知道呢?我能想到的一个选项是在视图中包含一个隐藏字段,其中包含页面模板的实际运行时类型的名称.我想这是一个黑客攻击,但是因为你在简单之后,我认为它会好起来的.在这种情况下,只需RuntimeTypeName在TemplateBase类中包含一个名为的属性:
public string RuntimeTypeName { get { return GetType().FullName; } }
Run Code Online (Sandbox Code Playgroud)
由于它只是调用GetType(),默认情况下是所有类型重写的虚方法,因此它将返回运行时模板类型的名称.
然后,您必须确保为TemplateBase实现创建的部分视图包含TemplateBase.RuntimeTypeName属性的(隐藏)字段.换句话说,在SingleColumnTemplate.ascx和TwoColumnTemplate.ascx你有这样一行:
<%: Html.HiddenFor(m => m.RuntimeTypeName) %>
Run Code Online (Sandbox Code Playgroud)
利用此信息创建正确类型的模板的模型绑定器可能如下所示:
/// <summary>
/// Model binder hack that builds upon the DefaultModelBinder,
/// but that can detect the "proper" subclass/implementing class
/// type for a model, assuming the name of that type is contained
/// in a field called "RuntimeTypeName".
/// </summary>
public class InheritanceSupportingModelBinder : DefaultModelBinder
{
// Assume that the name of the field that contains the
// runtime type name is called "RuntimeTypeName"
public const string RuntimeTypeNameField = "RuntimeTypeName";
private Type RuntimeType { get; set; }
// This method is called by the DefaultModelBinder to find out which
// properties of the current model that it should attempt to bind
protected override PropertyDescriptorCollection GetModelProperties(
ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// If we have found out the runtime type of the model through
// looking at the "special" field above, use the properties of that type.
// Otherwise, use the default behavior.
if (RuntimeType != null)
{
return TypeDescriptor.GetProperties(RuntimeType);
}
else
{
return base.GetModelProperties(controllerContext, bindingContext);
}
}
// This method is called by the DefaultModelBinder when it
// tries to create an instance of the model class. If the
// class is abstract, an exception will be thrown. Therefore
// we try to read the name of the actual type from the
// RuntimeTypeName (hidden) field and return an instance of that type.
protected override object CreateModel(ControllerContext controllerContext,
ModelBindingContext bindingContext,
Type modelType)
{
if (bindingContext.ValueProvider.ContainsPrefix(
bindingContext.ModelName + "." + RuntimeTypeNameField))
{
var result = bindingContext.ValueProvider.GetValue(
bindingContext.ModelName + "." + RuntimeTypeNameField);
if (result != null && !string.IsNullOrEmpty(result.AttemptedValue))
{
// Check that the type indicated by the hidden field is really
// a subclass of (or implementing) the indicated base class
var tempType = Type.GetType(result.AttemptedValue);
if (modelType.IsAssignableFrom(tempType))
{
RuntimeType = modelType = tempType;
}
}
}
return base.CreateModel(controllerContext, bindingContext, modelType);
}
}
Run Code Online (Sandbox Code Playgroud)
免责声明:我自己是ASP.NET MVC的初学者,所以这个模型绑定器可能有问题.我通过查看源代码DefaultModelBinder并通过反复试验将它放在一起.这只是一个例子,但根据我的(快速和肮脏)测试它似乎工作.
当然,您需要在Global.asax中注册它才能启动它:
ModelBinders.Binders.Add(
typeof(TemplateBase),
new InheritanceSupportingModelBinder());
Run Code Online (Sandbox Code Playgroud)
但是我们没有完成!请记住,AreaContainer.Areas集合是类型的IList<AreaBase>- 并且因为AreaBase它也是一个抽象类,我们必须应用相同的hack才能正确绑定它.也就是说,添加RuntimeTypeName属性的AreaBase类和注册我们自定义的模型绑定的AreaBase类Global.asax.
如果到目前为止我们已经执行了所有这些步骤,我们可以使用一种操作方法PageAdminController来处理页面的编辑,如下所示:
[HttpPost]
public ActionResult Edit(Page page)
{
if (!ModelState.IsValid)
{
return View(page);
}
// TODO Save page to database or whatever
// TODO Redirect to page index
}
Run Code Online (Sandbox Code Playgroud)
创建新页面的操作方法留作练习,不应该那么困难(用户从列表中选择模板,显示正确的表单,如上所述的后处理操作).
显示页面应该是微不足道的,只需使用HtmlHelper.DisplayFor(...)代替EditorFor(...),创建相应的部分视图并进行设置.
对于WYSIWYG内容编辑,您可能希望使用第三方组件.CKEditor,TinyMCE,YUI富文本编辑器和Telerik编辑器就是一些例子.
这是我对此的看法!欢迎所有评论; 正如我所提到的,我自己正在学习ASP.NET MVC,如果我的错误被那些了解得更好的人指出,那将会很棒.
| 归档时间: |
|
| 查看次数: |
1727 次 |
| 最近记录: |