• Orchard模块开发全接触2:新建 ProductPart


    一:创建 Part

    1:项目引用 Orchard.Framework;

    2:创建 Models 文件夹;

    3:在 Models 文件夹下创建类 ProductPartRecord,如下:

    public class ProductPartRecord : ContentPartRecord
    {
        public virtual decimal UnitPrice { get; set; }
        public virtual string Sku { get; set; }

    }

    注意,为 virtual,因为 orchard 的 NHIBERNATE 需要这样。

    以及 ProductRecord:

    public class ProductPart : ContentPart<ProductPartRecord>
    {
        public decimal UnitPrice
        {
            get { return Record.UnitPrice; }
            set { Record.UnitPrice = value; }
        }

        public string Sku
        {
            get { return Record.Sku; }
            set { Record.Sku = value; }
        }
    }

     

    二:更新数据库

    更新数据库,依赖于一个叫 Migrations 的类型,我们需要创建在 根目录下,如下:

    public class Migrations : DataMigrationImpl
    {
        public int Create()
        {

            SchemaBuilder.CreateTable("ProductPartRecord", table => table
                // The following method will create an "Id" column for us and set it is the primary key for the table
                .ContentPartRecord()
                // Create a column named "UnitPrice" of type "decimal"
                .Column<decimal>("UnitPrice")
                // Create the "Sku" column and specify a maximum length of 50 characters
                .Column<string>("Sku", column => column.WithLength(50))
                );

            // Return the version that this feature will be after this method completes
            return 1;
        }
    }

    如果不知道 Migrations 的用法,可参考:Orchard之Module升级,现在,我们查询数据库:

    image

    可以看到代码已经执行,然后,表 TMinji_Shop_ProductPartRecord 也已经被创建了。

    image

    三:创建 ProductPart

    上面,我们创建了 ProductPart 这个类,但是还不够,我们需要把这个类更新到 ContentPartDefinition 这个表中,并且,我们需要注明 ProductPart 是 attachable 的,即:需用用户在后台附加(attach)ProductPart。

    现在,我们继续通过代码来做到这一点,我们仍旧在 Migrations 中做,这回,我们首先要引入 Orchard.Core,然后增加下面的代码:

    image

    编译,刷新下后台,查看数据库:

    image

    发现 version 为 2 了,并且,Settings_ContentPartDefinitionRecord 表多了行数据:

    image

    并且,进入后台

    image

    发现,多了:

    image

    Edit 之,发现为:

    image

    这正是我们的代码所定义的。

    四:添加 Driver

    现在,我们 Content -> Content Types and Create new Type,取名为 Book,并且,选择:Body, Comments, Product, Title, Autoroute, and Tags ,然后保存,然后,重复以上,添加 DVD。

    当到了这个时候,如果我们去添加 book,我们会发现,并没有看到 Price 和 SKU,它们在哪里呢?是的,我们还缺少一个 Driver,

    Driver 类似于 MVC 控制器,但是它对 contentpart 负责。典型的,它有三个方法:一个用于 part 的前台显式,一个用于后台 edit 模式下的显式,一个用于处理用户在保存 content item的时候(这个时候,part 被 attached)。

    其返回值为 DriverResult,当然,大部分情况下,实际上返回为 ShapeResult(从 DriverResult 继承)。ShapeResult 告诉 Orchard,Razor 模版如何 render part。

    现在,创建之:

    1:首先,创建 Drivers 目录;

    2:创建 ProductPartDriver:

    using Orchard.ContentManagement;
    using Orchard.ContentManagement.Drivers;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using TMinji.Shop.Models;

    namespace TMinji.Shop.Drivers
    {
        public class ProductPartDriver : ContentPartDriver<ProductPart>
        {

            protected override string Prefix
            {
                get { return "Product"; }
            }

            protected override DriverResult Editor(ProductPart part, dynamic shapeHelper)
            {
                return ContentShape("Parts_Product_Edit", () => shapeHelper
                    .EditorTemplate(TemplateName: "Parts/Product", Model: part, Prefix: Prefix));
            }

            protected override DriverResult Editor(ProductPart part, IUpdateModel updater, dynamic shapeHelper)
            {
                updater.TryUpdateModel(part, Prefix, null, null);
                return Editor(part, shapeHelper);
            }

        }

    }

    现在,有必要对代码进行一下说明:

    1:当前的 Driver 有两个方法,一个在显示 ProductPart 的 editor 的时候被嗲用,一个在后台提交 editor 表单的时候被调用(含 updater 的那个方法)。

    2:我们把我们的 shape 命名为 Parts_Product_Edit,这样子,它的视图就是 Views/EditorTemplates/parts/product.cshtml。

    现在,不妨来添加这个视图

    @using System.Web.Mvc.Html
    @model TMinji.Shop.Models.ProductPart
    <fieldset>
        <legend>Product Fields</legend>

        <div class="editor-label">@Html.LabelFor(x => x.Sku)</div>
        <div class="editor-field">
            @Html.EditorFor(x => x.Sku)
            @Html.ValidationMessageFor(x => x.Sku)
        </div>
        <div class="hint">Enter the Stock Keeping Unit</div>

        <div class="editor-label">@Html.LabelFor(x => x.UnitPrice)</div>
        <div class="editor-field">
            @Html.EditorFor(x => x.UnitPrice)
            @Html.ValidationMessageFor(x => x.UnitPrice)
        </div>
        <div class="hint">Enter the sales price per unit</div>
    </fieldset>

    为了让这个视图能正确呈现,我们还需要就加入引用

    System.Web
    System.Web.Mvc
    System.Web.WebPages

    前者在 全局程序集 下,后两者,则可以在 libaspnetmvc 下可以找到(顺注:你一定知道这个 lib 就是哪个 lib)。

    然后,我们根目录还缺少一个 web.config,我建议你直接从 blog 那个模块下面进行拷贝,(顺注:我的 orchard 是 1.8 版本):

    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <remove name="host"/>
          <remove name="pages"/>
          <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
          <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
        </sectionGroup>
      </configSections>
      <system.web.webPages.razor>
        <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
          <namespaces>
            <add namespace="System.Web.Mvc"/>
            <add namespace="System.Web.Mvc.Ajax"/>
            <add namespace="System.Web.Mvc.Html"/>
            <add namespace="System.Web.Routing"/>
            <add namespace="System.Web.WebPages"/>
            <add namespace="System.Linq"/>
            <add namespace="System.Collections.Generic"/>
            <add namespace="Orchard.Mvc.Html"/>
          </namespaces>
        </pages>
      </system.web.webPages.razor>
      <system.web>
        <compilation targetFramework="4.5">
          <assemblies>
            <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            <add assembly="System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            <add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
          </assemblies>
        </compilation>
      </system.web>
    </configuration>

    然后,在根目录下,在创建一个 Placement.info,

    <Placement>
      <Place Parts_Product_Edit="Content:1" />
    </Placement>

    这是告诉 Orchard,请显式在 Widget 的 Content 部位。

    现在,我们可以看到:

    image

    五:添加 handler(持久化数据)

    我们来添加下面的数据:

    Books:

    • The Hobbit, $50, SKU-1001
    • Wizard's First Rule, $39, SKU-1002
    • The Hunger Games, $29, SKU-1003

    DVDs:

    • Prometheus, $30, SKU-1004
    • The Shawshank Redemption, $25, SKU-1005
    • The Dark Knight, $20, SKU-1006

    然后,保存成功,然后,我们打算修改这些数据,结果发现 Price 和 Sku 是空的,这是为什么呢?因为我们还没有实现持久化哦。要让 Orchard 持久化数据,我们需要:

    1:创建 Handlers 文件夹;

    2:添加 ProductPartHandler,如下:

    public class ProductPartHandler : ContentHandler
    {
        public ProductPartHandler(IRepository<ProductPartRecord> repository)
        {
            Filters.Add(StorageFilter.For(repository));
        }
    }

    现在,我们发现可以增删数据了。去查查数据库吧:

    image

  • 相关阅读:
    根据字符串拆分字符串
    .NET WinForm读取扫描枪从COM口传过来的数据,显示在TextBox中,并做其他操作。
    《将博客搬至CSDN》
    mysql学习(二)DML
    mysql学习(一)DDL
    BigDecimal
    排序
    2017
    oracle的mapper小结
    数据结构查找
  • 原文地址:https://www.cnblogs.com/luminji/p/3858330.html
Copyright © 2020-2023  润新知