Orchard之Module开发

简介: 一:生成新项目 首先,要启动 Code Generation,参考《Orchard之生成新模板》。 其次,进入命令行,输入: codegen module Tminji.Requirement 这会在解决方案中生成一个新项目,如下:   二:路由匹配 在新项目中创建 Routes.

一:生成新项目

首先,要启动 Code Generation,参考《Orchard之生成新模板》。

其次,进入命令行,输入:

codegen module Tminji.Requirement

这会在解决方案中生成一个新项目,如下:

image

 

二:路由匹配

在新项目中创建 Routes.CS 文件,编码如下:

public class Routes : IRouteProvider {
    #region IRouteProvider 成员

    public IEnumerable<RouteDescriptor> GetRoutes() {
        return new[] {
            new RouteDescriptor {
                Priority = 5,
                Route = new Route
                    (
                    "Requirement/{controller}/{action}/",
                    new RouteValueDictionary
                    {
                        {"area", "Tminji.Requirement"},
                        {"controller", "Home"},
                        {"action", "Index"}
                    },
                    new RouteValueDictionary(),
                    new RouteValueDictionary {{"area", "Tminji.Requirement"}},
                    new MvcRouteHandler()
                    )
            }
        };
    }

    public void GetRoutes(ICollection<RouteDescriptor> routes) {
        foreach (var routeDescriptor in GetRoutes()) {
            routes.Add(routeDescriptor);
        }
    }

    #endregion
}

 

三:新建控制器吧

接下来,就跟我们熟悉的 MVC 开发一样了,新建控制器,类似如下,可以创建视图,也可以没有视图,总之,输入 URL ,就会执行控制器代码了:

public class HomeController : Controller {
    public IOrchardServices Services { get; set; }

    public HomeController(IOrchardServices services) {
        Services = services;
        T = NullLocalizer.Instance;
    }

    public Localizer T { get; set; }

    public ActionResult Index()
    {
        string model = "Hello World!"; 
        return View((object)model);    
    }
    public string About()
    {
        return "About me";
    }

}

 

四:在后台启用之

如下:

image

 

五:实效

image

或:

image

 

六:操作数据库

如果上面显式的文本我们要存储在数据库,那么,怎么实现?

1:创建数据库表

我们可以有两种方式来创建数据库表,一种是通过 Module 的 Update,我们需要在项目的根目录下创建一个文件 Migrations.CS,内容大致如下:

public class Migrations : DataMigrationImpl
{
    public int Create()
    {
        return 1;
    }

    public int UpdateFrom1()
    {
        SchemaBuilder.CreateTable("RequirementRecord", table => table
            .ContentPartVersionRecord()
            .Column<int>("Id", column => column.PrimaryKey().Identity())
            .Column<string>("Content", column => column.WithLength(200))
        );
        ContentDefinitionManager.AlterPartDefinition("Tminji.Requirement",
            builder => builder.Attachable());
        return 2;
    }
}

这样,在我们下次登录后台的时候,就会在 Module 旁边,看到 Update,然后点击后,就会执行上述代码。

还有一种,当然是手动创建数据库表,这没有什么影响。数据库表是这样的:

image

2:实现后台管理这个 Content 的值

首先,我们得在 根目录下创建AdminMenu类型(备注:ORCHARD下很多命名都是固定死的,不能自己改变),如下:

public class AdminMenu : INavigationProvider {
    public Localizer T { get; set; }

    #region INavigationProvider 成员

    /* 指定这个菜单是一个管理菜单
     */
    public string MenuName {
        get { return "admin"; }
    }

    public void GetNavigation(NavigationBuilder builder) {
        builder
            .AddImageSet("Requirement") //设置菜单图标(Orchard中默认约定调用Styles目录下的menu.xxxxxx-admin.css样式文件来显示菜单前面的图标)
            .Add(
                T("Requirement"), //菜单文本
                "5", //菜单位置(Orchard会根据这个值对菜单进行排序)
                menu => menu.Action(new RouteValueDictionary
                    {
                        {"area", "Tminji.Requirement"},
                        {"controller", "Admin"},
                        {"action", "Index"}
                    })
            );
    }
    #endregion
}

其次,我们创建 AdminController(固定死),编码如下:

public class AdminController : Controller
{
    // GET: Admin
    private readonly IRequirementService _textService;

    public AdminController(IRequirementService textService)
    {
        _textService = textService;
    }

    public ActionResult Index()
    {
        var viewModel = new RequirementPart();
        var textRecord = _textService.GetText();

        if (textRecord != null)
        {
            viewModel.Content = textRecord.Content;
        }

        return View(viewModel);
    }

    [HttpPost, ActionName("Index")]
    [FormValueRequired("submit.Save")]
    public ActionResult IndexPost()
    {
        var viewModel = new RequirementPart();

        if (!TryUpdateModel(viewModel))
        {
            return Index();
        }

        //更新数据
        _textService.UpdateText(viewModel.Content);

        return RedirectToAction("Index");
    }
}

前台代码如下:

image

Admin下的 index.cshtml:

@using Tminji.Requirement.Models
@model RequirementPart

<!--设置标题-->
@{ Layout.Title = T("Manage Hello World Text").ToString(); }

@Html.ValidationSummary()

@using (Html.BeginFormAntiForgeryPost())
{
    <fieldset>
        @Html.LabelFor(m => m.Content)
        @Html.TextBoxFor(m => m.Content, new { @class = "text" })
    </fieldset>
    <fieldset>
        <button class="primaryAction" type="submit" name="submit.Save" value="yes">@T("Save")</button>
    </fieldset>
}

3:数据访问层

orchard 的数据访问层是使用 nhibernate 实现的,我们同样可以把其换成 ADO.NET 的,注意上面的控制器中,存在 IRequirementService,以及隐藏存在的这个接口的一个实现类(ORCHARD)自动会为我们找到它并注入到控制器中,在这里,我们可以这样实现:

public interface IRequirementService : IDependency
{
    RequirementPart GetText();

    RequirementPart UpdateText(string content);
}

[UsedImplicitly]
public class RequirementService : IRequirementService
{
    private readonly IRepository<Requirement> _textRepository;

    public RequirementPartService(IRepository<Requirement> textRepository)
    {
        _textRepository = textRepository;
    }

    #region ITextService 成员

    public Requirement GetText()
    {
        var conn = @"Data Source=xxx;Initial Catalog=OrchardOk1;Persist Security Info=True;User ID=sa;Password=xxx";
        var sql = @"SELECT * FROM RequirementRecord";
        var ds = SqlHelper.ExecuteDataset(conn, CommandType.Text, sql, null);
        if (ds.Tables[0].Rows.Count == 0)
            return null;
        return new Requirement()
        {
            Id = (int)ds.Tables[0].Rows[0][0],
            Content = (string)ds.Tables[0].Rows[0][1]
        };
    }

    public Requirement UpdateText(string content)
    {
        var conn = @"Data Source=xxx;Initial Catalog=OrchardOk1;Persist Security Info=True;User ID=sa;Password=xxx";
        string sql = "";
        var m = GetText();
        if (m == null)
        {
            sql = "INSERT INTO RequirementRecord (ID, [CONTENT]) VALUES (1, @CONTENT)";
        }
        else
        {
            sql = @"UPDATE RequirementRecord SET [CONTENT]=@CONTENT";
        }

        var pms = new SqlParameter[] {
            new SqlParameter("@CONTENT", content)
        };
        SqlHelper.ExecuteNonQuery(conn, CommandType.Text, sql, pms);
        return new Requirement()
        {
            Id = 1,
            Content = content,
        };
    }

    #endregion
}

至于 home/index 这里,同理,就不在赘述了。

后台管理的实效如下:

image

Creative Commons License本文基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
目录
相关文章
|
网络协议 机器人 Python
关于运行robot framework 报错解决方法,ModuleNotFoundError: No module named 'robot'
关于运行robot framework 报错解决方法,ModuleNotFoundError: No module named 'robot'
关于运行robot framework 报错解决方法,ModuleNotFoundError: No module named 'robot'
|
4月前
|
JavaScript
Vue 开发中的一些问题简单记录,Cannot find module ‘webpack/lib/RuleSet‘
Vue 开发中的一些问题简单记录,Cannot find module ‘webpack/lib/RuleSet‘
285 1
|
Java
RestfulTool
RestfulTool
60 0
|
JavaScript
UniApp 解决 Error: Cannot find module ‘webpack/lib/RuleSet‘
UniApp 解决 Error: Cannot find module ‘webpack/lib/RuleSet‘
969 0
ts重点学习141-使用webpack打包ts文件
ts重点学习141-使用webpack打包ts文件
83 0
ts重点学习141-使用webpack打包ts文件
|
前端开发 JavaScript 编译器
前端模块简史 - CJS & *MD & ES Modules & SystemJS & Webpack
最近这些年前端发展速度迅猛,而前端的模块化方案也在不断的更新,这里记录整理下工作 8 年所了解的一些关于前端模块化的知识,顺便 “考下古” ,由于涉及的内容较多不是每个都很了解,只能尽量保证输出内容的准确性。
前端模块简史 - CJS & *MD & ES Modules & SystemJS & Webpack
ts重点学习142-使用webpack打包ts文件笔记
ts重点学习142-使用webpack打包ts文件笔记
125 0
|
API Python Windows
成功解决Scrapy框架的问题ModuleNotFoundError: No module named 'win32api'
成功解决Scrapy框架的问题ModuleNotFoundError: No module named 'win32api'
成功解决Scrapy框架的问题ModuleNotFoundError: No module named 'win32api'
|
C++
SystemC Tutorial 2 Module
模块(Module)模块是SystemC设计中的基本设计单元。模块可以使得设计者将一个复杂的系统分割为一些更小但易于管理的部分。SystemC模块的功能和作用与HDL语言中的模块是类似的。定义的模块也可以像HDL语言一样包含端口、信号、其他模块、处理过程和结构体,这些单元实现用以实现模块的功能。通过端口可以将几个模块连接起来。模块被保存为 .h 文件。如果在一个模块中调用其他模块,只需像C++中引
345 0
|
JavaScript 前端开发
webpack4.0各个击破(5)—— Module篇
webpack4.0各个击破(5)—— Module篇 webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高。本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决方式的模式,以前端构建中遇到的具体需求为出发点,学习webpack工具中相应的处理办法。
1404 0