• Orchard之Module开发


    一:生成新项目

    首先,要启动 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

  • 相关阅读:
    用jQuery File Upload做的上传控件demo,支持同页面多个上传按钮
    从炉石传说的一个自杀OTK说起
    DTCMS插件的制作实例电子资源管理(二)Admin后台页面编写
    DTCMS插件的制作实例电子资源管理(一)插件目录结构
    一个看似很简单的SQL却难倒了很多人
    一个js验证类
    elasticsearch节点间通信的基础transport
    elasticsearch cluster 详解
    elasticsearch cluster 概述
    Node组装启动过程
  • 原文地址:https://www.cnblogs.com/luminji/p/3831281.html
Copyright © 2020-2023  润新知