TextCotent 在Kooboo.CMS.Content下面,在View中有使用到这个模型层。

  TextContent继承了ContentBase,而ContentBase是由2个部分类组成的,一个是内容对象基类的子类,另一个是实现了持久化.那。。。我们该如何去理解呢,这里我用PS画一幅图大家就懂了。TextContent有3个构造函数,其中这2个构造函数都和基类(ContentBase)有关系。这3个构造函数分别如下:

        /// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
/// <param name="dictionary">The dictionary.</param>
public TextContent(IDictionary<string, object> dictionary)
: base(dictionary)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
public TextContent()
: base()
{
this.Id = string.Empty;
}
/// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
/// <param name="repository">The repository.</param>
/// <param name="schemaName">Name of the schema.</param>
/// <param name="folderName">Name of the folder.</param>
public TextContent(string repository, string schemaName, string folderName)
: base(repository, folderName)
{
this.Id = string.Empty;
this.SchemaName = schemaName;
}

  大家也许会疑惑这个TextContent有什么用处,看看视图里面的ViewBag.XXX你就明白了,其实ViewBag.XXX得到的是一个弱类型,可以强制转换成TextContent,为什么我这么自信它可以转换为TextContent呢?因为其实在数据库里建立的这张表和TextContent是一一对应的,字段的名称都是相同的。

下面的是TextContent的全部代码,大家有兴趣的可以对比一下,都是一样的。

#region License
//
// Copyright (c) 2013, Kooboo team
//
// Licensed under the BSD License
// See the file LICENSE.txt for details.
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using Kooboo.CMS.Common.Persistence.Non_Relational; namespace Kooboo.CMS.Content.Models
{
/// <summary>
/// 文本内容
/// </summary>
public class TextContent : ContentBase
{
/// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
/// <param name="dictionary">The dictionary.</param>
public TextContent(IDictionary<string, object> dictionary)
: base(dictionary)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
public TextContent()
: base()
{
this.Id = string.Empty;
}
/// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
/// <param name="repository">The repository.</param>
/// <param name="schemaName">Name of the schema.</param>
/// <param name="folderName">Name of the folder.</param>
public TextContent(string repository, string schemaName, string folderName)
: base(repository, folderName)
{
this.Id = string.Empty;
this.SchemaName = schemaName;
} /// <summary>
/// 内容对应的Schema(Content type)
/// </summary>
/// <value>
/// The name of the schema.
/// </value>
public string SchemaName
{
get
{
if (this.ContainsKey("SchemaName") && base["SchemaName"] != null)
{
return base["SchemaName"].ToString();
}
return null;
}
set
{
base["SchemaName"] = value;
}
} /// <summary>
/// 内嵌内容的父目录
/// </summary>
public string ParentFolder
{
get
{
if (this.ContainsKey("ParentFolder") && base["ParentFolder"] != null)
{
return base["ParentFolder"].ToString();
}
return null;
}
set
{
base["ParentFolder"] = value;
}
}
/// <summary>
///内嵌内容的父内容的UUID
/// </summary>
public string ParentUUID
{
get
{
if (this.ContainsKey("ParentUUID") && base["ParentUUID"] != null)
{
return base["ParentUUID"].ToString();
}
return null;
}
set
{
base["ParentUUID"] = value;
}
} /// <summary>
/// Gets the type of the content.
/// </summary>
/// <value>
/// The type of the content.
/// </value>
public override ContentType ContentType
{
get
{
return ContentType.Text;
}
}
/// <summary>
/// 内容被广播过来的源UUID
/// </summary>
public string OriginalUUID
{
get
{
if (this.ContainsKey("OriginalUUID") && base["OriginalUUID"] != null)
{
return base["OriginalUUID"].ToString();
}
return null;
}
set
{
base["OriginalUUID"] = value;
}
}
/// <summary>
/// 内容被广播过来的源仓库
/// </summary>
public string OriginalRepository
{
get
{
if (this.ContainsKey("OriginalRepository") && base["OriginalRepository"] != null)
{
return base["OriginalRepository"].ToString();
}
return null;
}
set
{
base["OriginalRepository"] = value;
}
}
/// <summary>
/// 内容被广播过来的源目录
/// </summary>
public string OriginalFolder
{
get
{
if (this.ContainsKey("OriginalFolder") && base["OriginalFolder"] != null)
{
return base["OriginalFolder"].ToString();
}
return null;
}
set
{
base["OriginalFolder"] = value;
}
}
/// <summary>
///内容被广播过来后是否本地化了
/// </summary>
public bool? IsLocalized
{
get
{
if (this.ContainsKey("IsLocalized") && base["IsLocalized"] != null)
{
return (bool)base["IsLocalized"];
}
return true;
}
set
{
base["IsLocalized"] = value;
}
} /// <summary>
/// 内容的排序顺序
/// </summary>
public int Sequence
{
get
{
if (this.ContainsKey("Sequence") && base["Sequence"] != null)
{
return Convert.ToInt32(base["Sequence"]);
}
return ;
}
set
{
base["Sequence"] = value;
}
} /// <summary>
/// 内容是否有附件
/// </summary>
/// <returns>
/// <c>true</c> if this instance has attachment; otherwise, <c>false</c>.
/// </returns>
public bool HasAttachment()
{
var schema = this.GetSchema();
foreach (var column in schema.AsActual().Columns.Where(it => string.Compare(it.ControlType, "File", true) == ))
{
var value = this[column.Name];
if (value != null && !string.IsNullOrEmpty(value.ToString()))
{
return true;
}
}
return false;
} /// <summary>
/// 保存时,要存储的附件
/// </summary>
public IEnumerable<ContentFile> ContentFiles { get; set; } /// <summary>
/// Called when [saving].
/// </summary>
protected override void OnSaving()
{
base.OnSaving();
this.UserKey = UserKeyGenerator.DefaultGenerator.Generate(this);
} #region override object
public override bool Equals(object obj)
{
if (!(obj is ContentBase))
{
return false;
}
var c = (ContentBase)obj;
if (this.UUID.EqualsOrNullEmpty(c.UUID, StringComparison.CurrentCultureIgnoreCase))
{
return true;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion public bool ___EnableVersion___
{
get
{
if (this.ContainsKey("___EnableVersion___") && base["___EnableVersion___"] != null)
{
return (bool)base["___EnableVersion___"];
}
return true;
}
set
{
base["___EnableVersion___"] = value;
}
} #region MoreOptionsOnBroadcasting
public int OriginalUpdateTimes
{
get
{
if (this.ContainsKey("OriginalUpdateTimes") && base["OriginalUpdateTimes"] != null)
{
return (int)(base["OriginalUpdateTimes"]);
}
return ;
}
set
{
base["OriginalUpdateTimes"] = value;
}
}
public int OriginalLastestVisitedVersionId
{
get
{
if (this.ContainsKey("OriginalLastestVisitedVersionId") && base["OriginalLastestVisitedVersionId"] != null)
{
return Convert.ToInt32(base["OriginalLastestVisitedVersionId"]);
}
return ;
}
set
{
base["OriginalLastestVisitedVersionId"] = value;
}
}
#endregion
}
}

大家有没有发现,代码里面没有Title,Photo和Description这3个字段,那么这3个字段又是从哪里来的呢?看下面的图,原来是我们在内容类型里面自定义的。

我们可以查看一下这3个字段在数据库中的类型:

这里证明了一点,至少证明了一点,Kooboo CMS在对于String 类型的字符串,只要你没有设置长度的话,默认是到最长,这里补充一点,长度在Kooboo CMS中是可以去设置的,在这里设置。

  好了,下面来讲解一下各个字段的用途。

  • UUID:类似于Guid码,Kooboo CMS自己定义的一套生成编码的规则方法所生成的不定字符串。
  • Repository:仓库,一个网站就是一个仓库,你可以把仓库理解为网站的名称,但是不是显示名称,这个名称是建立了就不可修改的。
  • FolderName:文件夹名称。
  • UserKey:下面的是这么解释的。。。。。这个主要是用在条件过滤的时候
        /// <summary>
/// 根据Summary字段生成的一个友好的唯一主键值,一般用于在URL中传递。
/// </summary>
public string UserKey
{
get
{
if (this.ContainsKey("UserKey") && base["UserKey"] != null)
{
return base["UserKey"] == null ? "" : base["UserKey"].ToString();
}
return null;
}
set
{
base["UserKey"] = value;
}
}

下面的图将会为你解释UserKey的作用,当然前提是你需要一个Summary 概述字段,Summary字段是自己去勾选的,在CMS的后台里面。

而配置UserKey的地方在View里面的数据查询可以配置。

看到了吗,其实这里可以进行内容过滤,如果是UserKey的话,那么就是下面这么一种写法。

UserKey=={UserKey} 这里的{UserKey}就是一个不定的参数,我个人感觉类似于string.Format()里面的{0}{1}这种形式的参数表示法。

我们再来想一下一个问题,为什么ContentBase要继承DynamicDictionary呢?我们先来看一下DynamicDictionary的结构,我这里为了简化只放出属性。

  public class DynamicDictionary : DynamicObject, IDictionary<string, object>
{
#region Fields
IDictionary<string, object> dictionary;
#endregion #region Properties
/// <summary>
/// Gets the count.
/// </summary>
/// <value>
/// The count.
/// </value>
int ICollection<KeyValuePair<string, object>>.Count
{
get
{
return dictionary.Count;
}
}
#endregion }

  其实说白了就是字典的扩展嘛。其实说简单一点,就是基类对象里面如果有UserKey的话,那么就会用get方法得到其值其余的就不多说了,大多是描述字段。

这里最后在介绍一下ContentBase对于IPersistable的支持。

本来想说一下的,但是太晚了,而且这个太难,做个记号,以后懂了再讲解。

    /// <summary>
/// ContentBase对IPersistable的实现
/// </summary>
public partial class ContentBase : IPersistable
{
/// <summary>
/// The content integrate id composite of Repository, FolderName and UUID. example: Repository#FolderName#UUID
/// </summary>
public string IntegrateId
{
get
{
return new ContentIntegrateId(this).ToString();
}
}
#region IPersistable Members private bool isDummy = true;
bool IPersistable.IsDummy
{
get { return isDummy; }
} void IPersistable.Init(IPersistable source)
{
isDummy = false;
} void IPersistable.OnSaved()
{
isDummy = false;
} void IPersistable.OnSaving()
{
OnSaving();
}
protected virtual void OnSaving()
{
if (string.IsNullOrEmpty(this.UUID))
{
this.UUID = UUIDGenerator.DefaultGenerator.Generate(this);
}
} #endregion }

Kooboo CMS 之TextContent详解的更多相关文章

  1. Kooboo CMS - Html.FrontHtml[Helper.cs] 各个方法详解

    下面罗列了方法详解,每一个方法一篇文章. Kooboo CMS - @Html.FrontHtml().HtmlTitle() 详解 Kooboo CMS - Html.FrontHtml.Posit ...

  2. Kooboo CMS - @Html.FrontHtml().Meta()详解。

    下面是代码: public virtual IHtmlString Meta() { AggregateHtmlString htmlStrings = new AggregateHtmlString ...

  3. Kooboo CMS - Html.FrontHtml.Position 详解

    DataContract 数据契约 http://www.cnblogs.com/Gavinzhao/archive/2010/06/01/1748736.html https://msdn.micr ...

  4. GC:并行回收CMS详解

    CMS详解 https://www.cnblogs.com/ggjucheng/p/3977612.html CMS默认不回收Perm, 需要加参数 +CMSPermGenSweepingEnable ...

  5. NopCommerce源码架构详解--初识高性能的开源商城系统cms

    很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...

  6. Kooboo CMS技术文档之三:切换数据存储方式

    切换数据存储方式包括以下几种: 将文本内容存储在SqlServer.MySQL.MongoDB等数据库中 将站点配置信息存储在数据库中 将后台用户信息存储在数据库中 将会员信息存储在数据库中 将图片. ...

  7. Kooboo CMS技术文档之二:Kooboo CMS的安装步骤

    在IIS上安装Kooboo CMS Kooboo CMS安装之后 安装的常见问题 1. 在IIS上安装Kooboo CMS Kooboo CMS部署到正式环境相当简单,安装过程是一个普通MVC站点在I ...

  8. 详解Java GC的工作原理+Minor GC、FullGC

    详解Java GC的工作原理+Minor GC.FullGC 引用地址:http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html J ...

  9. 服务器.htaccess 详解以及 .htaccess 参数说明(转载)

    htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户,所能使用的命令受到限 ...

随机推荐

  1. 一眼看懂深浅拷贝(clone)-C#

    这是使用的是序列化的方式实现深拷贝 [Serializable] class Person:ICloneable { /// <summary> /// 字符串在clone 中类似于值类型 ...

  2. 串口计时工具Grabserial简介及修改(添加输入功能)

    Grabserial是Tim Bird用python写的一个抓取串口的工具,这个工具能够为收到的每一行信息添加上时间戳. 如果想对启动时间进行优化的话,使用这个工具就可以简单地从串口输出分析出耗时. ...

  3. 数据分析之Numpy基础:数组和适量计算

    Numpy(Numerical Python)是高性能科学计算和数据分析的基础包. 1.Numpy的ndarray:一种多维数组对象 对于每个数组而言,都有shape和dtype这两个属性来获取数组的 ...

  4. ubuntu 安装与开始学习

    下载地址 http://cn.ubuntu.com/download/ 经验: 1.遇到安装问题,首先尝试解读错误,再使用  ./configure --help  不行再上Stack overflo ...

  5. 一鼓作气 博客--第一篇 note1

    1. 语言的类型 ,编译型(c,c++),解释型(python,php,ruby,java),编译型可移植性差,优点是运行速度快,解释型语言特点:边执行边翻译,速度慢. 2.翻译官就是机器的解释器,跟 ...

  6. WebServer+ADO+百万数据查询

    很简单的demo,查询速度快,易理解,废话不说  上demo 看完就明白了 源码地址:http://files.cnblogs.com/files/SpadeA/WebDemo.zip 这是关于Web ...

  7. .NET面试题系列[12] - C# 3.0 LINQ的准备工作

    "为了使LINQ能够正常工作,代码必须简化到它要求的程度." - Jon Skeet 为了提高园子中诸位兄弟的英语水平,我将重要的术语后面配备了对应的英文. .NET面试题系列目录 ...

  8. 走向面试之数据库基础:二、SQL进阶之case、子查询、分页、join与视图

    一.CASE的两种用法 1.1 等值判断->相当于switch case (1)具体用法模板: CASE expression WHEN value1 THEN returnvalue1 WHE ...

  9. 算法数据结构(一)-B树

    介绍 B树的目的为了硬盘快速读取数据(降低IO操作次树)而设计的一种平衡的多路查找树.目前大多数据库及文件索引,都是使用B树或变形来存储实现. 目录 为什么B树效率高 B树存储 B树缺点 为什么B树效 ...

  10. Hadoop 裡的 fsck 指令

    Hadoop 裡的 fsck 指令,可檢查 HDFS 裡的檔案 (file),是否有 corrupt (毀損) 或資料遺失,並產生 HDFS 檔案系統的整體健康報告.報告內容,包括:Total blo ...