开发者社区> luminji> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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 需要这样。
+关注继续查看

一:创建 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

前者在 全局程序集 下,后两者,则可以在 lib\aspnetmvc 下可以找到(顺注:你一定知道这个 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

Creative Commons License本文基于Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Seata RPC 模块的重构之路
RPC 模块是我最初研究 Seata 源码开始的地方,因此我对 Seata 的 RPC 模块有过一些深刻研究,在我研究了一番后,发现 RPC 模块中的代码需要进行优化,使得代码更加优雅,交互逻辑更加清晰易懂,本着 “让天下没有难懂的 RPC 通信代码” 的初衷,我开始了 RPC 模块的重构之路。
7677 0
IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理
1、前言 一个安全的信息系统,合法身份检查是必须环节。尤其IM这种以“人”为中心的社交体系,身份认证更是必不可少。 一些PC时代小型IM系统中,身份认证可能直接做到长连接中(也就是整个IM系统都是以长连接为中心:身份鉴权、数据收发、文件传送等等)。
2573 0
Orchard模块开发全接触4:深度改造前台
这里,我们需要做一些事情,这些事情意味着深度改造前台: 1:为商品增加 添加到购物车 按钮,点击后功能实现; 2:商品排序; 3:购物车预览,以及添加 结算 按钮; 4:一个显式 购物车中有*个 商品 的widget;   一:添加到购物车 按钮 修改 Views/Parts/Product.
534 0
Orchard模块开发全接触3:分类的实现及内容呈现(Display)
一:分类用现有技术怎么实现? 实际就是创建 Query 和 Projection,如果不知道怎么做,参考:Orchard之在前台显式一个属于自己的列表(在这篇里,还进行了稍稍拓展),当然,基础的知道,我们可以参考 Orchard 相关文档,不难。
684 0
Twitter模块开发
 Twitter模块开发 关于Twitter这一块,自发这篇博文之后有很多人问我,有的验证成功了不跳转,或者其它原因什么的 =======我看了一下,这篇博文里面有写呀,下面以红色粗体文字注明一下  Twitter和Facebook,就类似于国内的微博,或者分享功...
934 0
+关注
luminji
微软最有价值技术专家(MVP),著有《编写高质量代码:改善C#程序的157个建议》,有着十多年的软件从业资历。
291
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载