讲AX2012 Enerprise portal的开发,当然是在已经成功安装部署EP站点的基础上进行,这里不具体讲EP的安装部署,但在做开发时最好创建一个单独的EP开发站点,和生产用门户站点连接到同一台AOS服务,使用同样的生产数据库,在开发站点上测试正确后再导出到正式站点上部署使用。创建开发站点有几种方式,最简单的在AX Client中通过System administration>Setup>Enterprise Portal>Web sites>Create site来创建,注意新站点的URL,如果已有的EP站点是在Sharepoint应用的根节点下,那么新建的的站点需要使用http://epserver:port/sites/develop注意的路径。如果不想和正式站点使用同样的HTTP端口,可以在Sharepoint管理站点中使用其他非80端口创建的一个新Sharepoint应用,然后使用AX的安装程序在这个新的Application上安装门户。无论是哪种方式创建的站点,在System administration>Setup>Enterprise Portal>Web sites都会列出,需要注意的是在这个窗口上“Default Enterprise Portal site”的选择,这里选择的站点是你在AOT中“Depoly element”时部署的站点,所以比较好的方式将默认EP站点设为开发站点,开发测试完成后,使用System administration>Setup>Enterprise Portal>Deployments将开发更新部署到正式站点上。
页面和导航
打开AX2012的EP站点,最先注意到的可能是最上面导航菜单的Home、Procurement、Sales等链接。与此对应,整个EP站点的结构是从AOT/Web/Web module开始的,在Home下是Finance、Purchase、Sales等Web子模块,反映到EP站点上就是Home站点下的各个子Procurement、Sales等各个子站点,每个Web module的MenuitemName对应一个Web菜单项,这些菜单项指定的URL出现在顶部导航栏中,注意Finance模块没有出现在顶部导航栏中,这是因为其ShowLink属性设置为No,财务的信息毕竟不应该是对所有人都开放的,当然使用链接也是能导航到财务子站点的。Web moudle另外一个很重要的属性是QuickLauch,它指定一个Web menu,Web menu下包含多个子一级Web menu和Web menu items,而这些Web menu items所代表的URL就是出现在网页左边导航栏中的链接。
从上面Web module的导航已经能看出,大多数我们能打开的页面都是通过Web menu item指定的链接打开的,更确切的说是AOT/web/web menu items/urls下定义的URL类型的web菜单项,它最重要的属性就是url,看sales站点下的“Customers”页面,它的menuitem为“CustomerList”,相应的URL是“Sales/Enterprise%20Portal/customers.aspx”,一般链接的开始部分是相应的模块,接下来是Enterprise%20Portal,再接下来是页面的名称,那么这些页面又是哪里来的呢?在任何一个站点上“view all site contents”,“document libraries”下有个“Enterprise portal”,站点所有的页面就保存在这里,AOT中URL的web menu item所指向的就是这些页面,其实普通Sharepoint站点所创建的aspx页面也是保存在document library中的,只是AX EP站点在安装部署时已经部署了这些默认页面。我们知道可以直接在Sharepoint的站点添加aspx的新页面,AX EP站点当然也是一样,EP站点的页面一般都是web part page类型,因为你看到的AX的内容都是通过web part来显示的。创建了一个新的页面并保存到“Enterprise portal”的文档库后,我们回到AX添加相应的URL Menu item指向该页面,以便在QuickLaunch或者其他Web menu中链接到这个新的页面。一个问题是如果我们在开发EP中创建了一个页面,它是不会自动出现在其他门户站点中的,在AOT中找到页面对应的URL web menu item,右键中点击“Import page”,这样就会将页面的内容(HTML源码)导入到AOT中,就是AOT/Web/Web files/Page definitions下的内容,找到一个Page definitions,可以在属性中设置页面的标题等等。在AOT中右键点击某个page defintions,使用菜单中的“Deploy element”就可以将该页面部署到当前激活的部署站点。
再来看看一个页面上的具体内容是怎么呈现出来的,使用“Edit page”是可以直接在站点上编辑页面的,以/Sales/Enterprise%20Portal/default.aspx页面为例,“Edit page”后可以看到底部的链接栏和Ribbon的工具栏是不能编辑的,其他的都是一些Web parts,比如左边显示的QuickLauch链接菜单、所有客户的列表、一个名为Dynamic infolog webpart。点击一个Web part的下拉菜单可以通过“Edit web part”来修改它的一些属性,多数属性是Web part外观方面的,有的属性可能是AX Web part专有的。但是在属性中我们也没法知道Web part具体是什么类型,这时候我们可以打开页面的源码来查看,在AOT中找到相应的Page defintions双击打开就能看到页面的定义,如果安装了sharepoint designer,也可以使用它打开页面的源代码。两者显示的内容是不一样的,Page definitions并非是标准的aspx/html的源码,只包含页面上Web part的定义,比如/Sales/Enterprise%20Portal/default.aspx的页面定义default_sales,左边QuickLauch Web part的部分是这样的:
<AllUsersWebPart><![CDATA[<webParts> <webPart xmlns="http://schemas.microsoft.com/WebPart/v3"> <metaData> <type name="Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts.QuickLaunchWebPart, Microsoft.Dynamics.Framework.Portal, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <importErrorMessage>Cannot import this Web Part.</importErrorMessage> </metaData> <data> <properties> <property name="AllowClose" type="bool">True</property> <property name="AllowConnect" type="bool">True</property> <property name="AllowEdit" type="bool">True</property> ...... <property name="Hidden" type="bool">False</property> <property name="ID" type="string">g_6a41cc75_ea64_4fa2_ac38_cbdb57015474</property> <property name="TitleIconImageUrl" type="string" /> <property name="TitleUrl" type="string"> </property> <property name="UpdateMode" type="System.Web.UI.UpdatePanelUpdateMode, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">Conditional</property> <property name="WebPartRole" type="Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts.WebPartRole, Microsoft.Dynamics.Framework.Portal, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">None</property> <property name="Width" type="unit" /> <property name="ZoneID" type="string">LeftColumn</property> <property name="ZoneIndex" type="int">0</property> </properties> </data> </webPart> </webParts>]]></AllUsersWebPart>
“<metadata><type>”元素显示了QuickLanch是来自于程序集Microsoft.Dynamics.Framework.Portal的Web控件Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts.QuickLaunchWebPart。而在sharepoint designer中我们看到的相关部分是这样的:
<WebPartPages:WebPartZone runat="server" Title="loc:LeftColumn" ID="LeftColumn" FrameType="TitleBarOnly"> <ZoneTemplate> <dynamics:QuickLaunchWebPart runat="server" ManagedContentItem="DynamicsLeftNavigation" ID="g_04c12bda_c0ee_40f5_8389_1adab479c9fb" ExportMode="All" DefaultTitle="Dynamics QuickLaunch WebPart" CultureInfo="English (United States)" WebMenuName="EPSalesQuickLaunch" RequiresExternalContext="False" ChromeType="None" __MarkupType="vsattributemarkup" __WebPartId="{04C12BDA-C0EE-40F5-8389-1ADAB479C9FB}" WebPart="true" __designer:IsClosed="false"> </dynamics:QuickLaunchWebPart> </ZoneTemplate> </WebPartPages:WebPartZone>
QuickLanuch web part是通过“<dynamics:QuickLaunchWebPart runat="server" ManagedContentItem="DynamicsLeftNavigation”引入的,“WebmenuName”属性指定了所用的WEB菜单“EPSalesQuickLaunch”,“Dynamics” Tag prefix是在站点的web.config中注册的。Sharepoint designer显示的是我们熟悉的aspx页面的源代码,而Page definitions则是AX导入时加工过的页面定义,在部署时AX也会做相应处理转换为标准的aspx代码,所以如果我们要修改页面还是要在EP站点或者sharepoint desginer中修改页面,再回到AX中导入页面定义。
AX自带Webpart
从上面的内容也可以看到,安装部署EP站点时已经通过web.config默认引入和注册了一些AX的Web控件,这些web控件出现在在页面上添加Web part时的“Microsoft Dynamics AX”的分类下,下面来简单看看这些web part都有什么用。
- Action pane:在Sharepoint 2010中一些操作都放到一个Ribbon的工具栏中,包括页面编辑等一些Sharepoint的操作。EP的页面上添加Action pane的web part后,在属性中指定其Web menu,Web menu下的Web menu item就合并到Ribbon工具栏中显示。可以在页面上添加多个Action pane web part,它们会显示到一个Ribbon工具栏的不同标签页上。
- Bussiness overview:在属性中可以选择两种模式,Bussiness overview或者KPI list,分别显示分析服务的Measure或者KPI,可以手工添加要显示的Measure或者KPI项目,如果分析服务和EP服务不在同一台服务器上,你可能会遇到添加失败的错误,询问微软支持获取DynamicsAX2012-KB2744197 hotfix。
- Connect:它显示来自于微软AX社区的一些信息,在Role center的页面上默认添加。
- Cue:在属性中指定要显示的提示组(AOT/Parts/Cue groups)或者添加单独的一个提示,在AOT中可以创建一个Menu item指向一个cue,而可以在这个Menu item上再指定一个Web menu item,这样在EP页面上点击这个cue时可以打开相应的链接。
- Infolog:可以使用它给出提示消息,比如出错信息,在EP站点上创建的web part页默认会添加一个Infolog的web part,可以添加多个Infolog,但是只有第一个有用。后面我们可以看到如何在代码中将提示显示信息显示到Infolog上。
- Left Navigation:和模块的QuickLauch类似,显示一个Web菜单,可以用它来显示QuickLaunch之外的菜单项。
- List:这是一个很特别的Webpart。我们知道Client中有种List page类型的Form,比如所有客户列表的CustTableListPage,在AOT/Menu items/Display下有个同名的菜单项CustTableListPage指向这个Form。在EP页面上添加一个List的web part,其属性ListPageMenuItem指向 菜单项CustTableListPage,关闭页面编辑后就能显示出和Client中差不多的客户列表,这是怎么做到的呢?观察AOT中的CustTableListPage Form,首先看看Parts节点下的Form parts,DisplayTarget属性有的是Auto,有的是Client,Client强制Part只出现在Client程序中,而Auto的Form/Info parts则会同时在clien和EP上显示。与此类似的还有ActionPaneTab,只有EPaptabCustomer、EPaptabSell和EPaptabGeneral三个ActionPaneTab的DisplayTarget被设置为EP,它们将在EP页面上显示,其他的TAB都设置为Client在Client程序中显示。需要注意的是添加到ActionPaneTab中的Menu item是来自于AOT/Menu items/下的正常Client上的菜单项,而该菜单项的WebMenuItemName属性指定了出现在EP上的菜单项链接,比如CustTableNew菜单项的WebMenuItemName是CustomerNew。Form中其他一些控件基本上都有DisplayTarget属性,比如Grid及Grid下的字段相关的StringEdit控件,都是设为Auto所以也出现在EP页面上。除了在页面上手工添加一个List的Web part,还可以右键点击List page form的菜单项比如CustTableListPage,弹出菜单中选择Deploy To EP,AX会自动创建一个同名的页面,页面上添加List的web part并指向CustTableListPage菜单项,同时创建同名的和Web URL菜单项,我们可以添加这个Web菜单项到导航菜单来链接到这个新的页面。
- Page Title:它显示页面的标题,也可以显示来自于页面中其他web part的Label属性加上其当前会话的内容(Provider context,后面来讲),为此我们要建立web part直接的连接,在web part的编辑下拉菜单中选择Connections->Send AxPageTitle to然后选择相应的Page Title web part。
- Quick links:它可以显示和管理一组Link链接,方便用户打开相应的页面。可以给Quick links web part指定一个Quick links group ID,它会自动出现在Organization administration > Setup > Role center > Edit quick links窗口中,在这个窗口中点击Export to AOT可以将其下的链接导入到AOT的Resources节点下,这样操作的目的是为了后续也在该窗口中Import all from AOT部署到其他EP站点相同ID的Quick links组。
- QuickLaunch:在页面左边显示Web子模块的的Web菜单项,前面已经讲过了。
- Report:显示一个SSRS的报表,“Select a report”属性中选择一个报表名称,但并非所有的SSRS的报表都出现在这个列表中,适合在EP上显示的报表有一个ObjectType类型为SSRSReport的菜单项,因此那些通过控制类显示的报表是不能用在EP上的。
- Toolbar:工具栏方式显示一个Web菜单,在AX2009中用得很多,AX2012仍然支持但是推荐使用Action pane。
- Unified worklist:用在Role center的页面上显示来自于Alert、工作流审核、工作流任务的信息。
- User control:自定义的AX控件,“Managed content item”属性指定一个来自于AOT/Web/Web files/Web controls下的自定义控件,也是我们下面要详细讲解的内容。给一个User control的例子,在/Sales/Enterprise%20Portal/customers.aspx页面中点击一个Customer会打开一个客户详细信息的窗口,这个页面上显示客户所有信息字段的Web part就是一个user control,它的Managed content item来自于AOT/Web/Web files/Web controls/CustomerOverview。
自定义用户控件
EP中大多数的功能都是通过web part页面上添加User control + AX Web controls完成的,比如上面提到的查看/编辑客户详细信息用到的CustomerOverview web控件,EP开发的主要工作也就是开发自定义的web control。和开发SSRS报表类似,web控件的开发在VS中完成,在VS使用EP Web application模板创建一个C#工程,VS自动添加一些EP程序集的引用,并默认创建一个user control和default.aspx作为控件的测试页。EP的web control和普通aspx web control没有什么区别,只是因为reference引入了Microsoft.Dynamics.Framework.Portal下的一些组件,使用它们操作AX的数据,下面以实例来看看如何创建一个显示所有客户列表的控件QuickCustomerList。
创建一个EP web application工程,在工程添加一个新项,模板中选择Microsoft dynamic ax/EP web control命名为QuickCustomerList。打开QuickCustomerList的设计界面,在toolbox/dynamic ax下拖入AxDataSource组件,自动创建的ID为AxDataSource1。EP控件访问AX的数据主要是透过AxDataSource组件,设计界面菜单中选择Data set Name为CustomerList。CustomerList是预先创建在AOT/Data sets下的数据集,它类似于form下的Datasource节点,比如CustomerList数据集使用表CustTable和ContactPerson,ContactPerson表OutJoin到CustTable表。接下来我们再拖入AxGridView到EP控件设计界面,编辑菜单中“Choose data source”选择AxDataSource1,“Edit column”弹出对话框中选择“name**”字段,这就算完成了这个EP控件,完整的ascx文件如下:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="QuickCustomerList.ascx.cs" Inherits="QuickCustomerList" %> <dynamics:AxDataSource ID="AxDataSource1" runat="server" DataSetName="CustomerList" ProviderView="CustTable"> </dynamics:AxDataSource> <dynamics:AxGridView ID="AxGridView1" runat="server" BodyHeight="" DataKeyNames="RecId,ContactPerson!RecId" DataMember="CustTable" DataSetCachingKey="921a8d26-8934-4258-979d-5ef3ec5551ed" DataSourceID="AxDataSource1" EnableModelValidation="True"> <Columns> <dynamics:AxBoundField DataField="name**" DataSet="CustomerList" DataSetView="CustTable"> </dynamics:AxBoundField> </Columns> </dynamics:AxGridView>
我们可以直接在VS中测试QuickCustomerList控件,找到Default.aspx,页面上已经默认添加了一个AxInfoLog组件和一个AxUserControlWebPart,我们将AxUserControlWebPart的ManagedContentItem属性设置为QuickCustomerList,类似:
<asp:WebPartZone ID="Body" runat="server"> <ZoneTemplate> <dynamics:AxInfolog ID="AxInfolog1" runat="server" ExportMode="All" /> <dynamics:AxUserControlWebPart ID="AxUserControlWebPart1" ManagedContentItem="QuickCustomerList" runat="server" /> </ZoneTemplate>
在VS中运行EP application工程,IE显示的Default.aspx页面就能看到QuickCustomerList控件的结果。
要在实际EP站点中查看控件结果,首先要将EP applicaiton工程添加到AOT,包含的QuickCustomerList会自动出现在AOT/Web/Web files/Web controls和AOT/Web/Web content/Managed两个节点下。我们可以在已有的EP web part界面上使用QuickCustomerList,还可以点击AOT/Web/Web content/Managed下的QuickCustomerList,右键菜单中选择“Deploy to EP”,AX会在EP 站点中创建一个包含QuickCustomerList的同名页面,在网站document library中可以找到它打开浏览。
除了上面看到的AxDataSource和AxGridView组件,AX还提供了很多其他的组件,比如管理数据的容器AxForm、组织UI界面的AxSection/AxGroup、检索数据的AxLookup、显示报表的AxReportView等等,完整的列表以及它们的用法可以查看http://msdn.microsoft.com/en-us/library/cc617577.aspx。
上面的例子中没有写一句代码,实际的控件可能需要在C#的code file中编写大量的代码,比如下面的例子通过代码设置页面名称:
protected void Page_Load(object sender, EventArgs e) { ITitleProvider titleProvider = AxBaseWebPart.GetWebpart(this) as ITitleProvider; // Specify the title to pass as the AxPageTitle titleProvider.Caption = "Page title goes here"; // Do not include the context in the title titleProvider.ShowContext = false; }
在代码中使用InfoLog显示消息的例子:
using Proxy = Microsoft.Dynamics.Framework.BusinessConnector.Proxy; Proxy.Info objInfoLog = new Proxy.Info(this.AxSession.AxaptaAdapter); objInfoLog.add(Proxy.Exception.Warning, "This is a warning sent to the Infolog");
在EP工程中我们可以通过.net interop代理来使用X++的资源,AX已经预定义了一些代理工程,我们可以直接引用它们,在VS中右键点击EP工程,弹出菜单中选择“Add EP proxy project”选择你需要的代理工程,EPApplicationProxies是最常用的,包含了常用表/类的代理C#类。需要注意的是如果我们使用xpo导入代理工程,在编译EP控件时可能会碰到错误,需要右键点击AOT/Web/Web Files/Web Controls,弹出菜单中选择Generate Proxies for Compilation为EP控件重新生成代理类。
经常会遇到的一个问题是自定义开发的EP控件放到网页上后因为错误导致整个页面无法显示,想要删掉这个错误的控件也没办法,这时候我们可以在网页URL链接后添加参数contents=1,它会以列表的方式显示web part,而不是真正的渲染控件,这样方便我们删除错误的控件。
更多的有关EP控件编程的内容内容可以参见http://msdn.microsoft.com/en-us/library/cc588545.aspx。
其他
除了用户自定义控件,AX2012 R2引入了新的Chart control来显示图表,Chart control不能使用AxDataSource作为数据源,而是使用AxChartDataSource从AX获取数据。
Client中创建的Workflow在EP环境中也是可以使用的,添加AxWorkflowActionBar 到自定义web控件来显示workflow的相关操作,具体参见http://msdn.microsoft.com/en-us/library/ee677494.aspx。
结束语
EP开发的内容还是很多的,这里只是简单了解一下EP开发的主要内容,有机会单再来深入探讨。