我需要一個簡單的功能來添加頁面/更改這些頁面上的內容。我已經看過n2以及其他預構建CMS工具,但是這些方法可以爲我需要的簡單CMS功能提供高級功能。建立MVC CMS
什麼是最好的方法?我已經有一個MVC應用程序,我想補充/構建一個簡單的功能,如:
- 指定模板
- 添加區該模板
- 通過所見即所得的添加內容。
不確定從哪裏開始。
任何信息非常感謝。 感謝
這是.NET MVC
我需要一個簡單的功能來添加頁面/更改這些頁面上的內容。我已經看過n2以及其他預構建CMS工具,但是這些方法可以爲我需要的簡單CMS功能提供高級功能。建立MVC CMS
什麼是最好的方法?我已經有一個MVC應用程序,我想補充/構建一個簡單的功能,如:
不確定從哪裏開始。
任何信息非常感謝。 感謝
這是.NET MVC
假設你正在使用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; }
}
針對控制器動作編輯現有的頁面可能看起來是這樣的:
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);
}
// ...
}
在視圖(Views/PageAdmin/Edit.aspx
),這應該是強類型到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) %>
在文件夾Views/PageAdmin/EditorTemplates
,那麼你會放在爲每個模板和地區的部分修改意見類型(即SingleColumnTemplate.ascx
,TwoColumnTemplate.ascx
和HtmlArea.ascx
)。您可能還想爲AreaContainer
創建部分視圖。
至於接收編輯頁面的控制器動作,事情會變得更復雜一點。由於Page
具有TemplateBase
類型的屬性,這是一個抽象類,因此DefaultModelBinder
將不知道如何填充它。你可以通過編寫一個自定義模型綁定器來解決這個問題,該模型綁定器以某種方式「知道」要實例化的實現類。它會如何知道?我能想到的一個選擇是在視圖中包含隱藏字段,該字段包含頁面模板的實際運行時類型的名稱。我想,這有點破解,但是因爲你是在簡單之後,我認爲它會好起來的。在這種情況下,僅僅包括RuntimeTypeName
在TemplateBase
類稱爲屬性,例如:
public string RuntimeTypeName { get { return GetType().FullName; } }
因爲它只是調用GetType()
,這是所有類型的默認覆蓋的虛方法,它將返回的名稱運行時模板類型。
然後,您必須確保您爲TemplateBase
實施創建的部分視圖包含TemplateBase.RuntimeTypeName
屬性的(隱藏)字段。換句話說,在SingleColumnTemplate.ascx
和TwoColumnTemplate.ascx
你有這樣一行:
<%: Html.HiddenFor(m => m.RuntimeTypeName) %>
利用這些信息來創建正確類型的模板可能看起來像這樣的模型綁定:
/// <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);
}
}
免責聲明:我是ASP.NET MVC的初學者,所以這個模型綁定器可能會出錯。我通過查看DefaultModelBinder
的源代碼並通過反覆試驗將它放在一起。這只是一個例子,但根據我的(快速和骯髒)測試,它似乎工作。
當然,你需要在Global.asax將其註冊爲它踢:
ModelBinders.Binders.Add(
typeof(TemplateBase),
new InheritanceSupportingModelBinder());
但我們沒有這樣做!請記住,AreaContainer.Areas
集合的類型爲IList<AreaBase>
- 由於AreaBase
也是一個抽象類,我們必須應用相同的hack才能正確綁定它。也就是說,將RuntimeTypeName
屬性添加到AreaBase
類中,並在Global.asax
中註冊我們的AreaBase
類的定製模型聯編程序。
只要我們遵循所有這些步驟,到目前爲止,我們可以有一個動作方法,我們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
}
創建新頁面的操作方法作爲練習留下來,它不應該那麼困難(用戶從列表中選擇模板,顯示適當的表單,像上面那樣的後處理動作)。
顯示頁面應該是微不足道的,只需使用HtmlHelper.DisplayFor(...)
而不是EditorFor(...)
,創建相應的局部視圖並設置好。
對於所見即所得編輯的內容,您可能會想要使用第三方組件。 CKEditor,TinyMCE,YUI Rich Text Editor和Telerik Editor是一些例子。
這是我的承擔!所有意見都歡迎;正如我所提到的,我正在學習ASP.NET MVC,如果我的錯誤被更好的人指出,這將是非常好的。
這是ASP.NET MVC? – drew 2010-11-04 13:21:49
或者更好的是,「你使用的是哪個平臺」 - 我們可能會認爲.NET,但我們無法真正回答,直到你讓我們知道 – Murph 2010-11-04 13:39:32
既然他已經看過N2,我認爲他很清楚他使用的是ASP.NET 。考慮到這一點,許多人(特別是初學者)似乎將術語「MVC」視爲ASP.NET MVC框架的同義詞。但我只是猜測。 – 2010-11-04 19:28:56