参考了蒋金楠老师08年的文章。好吧,那时候我才大二、大三,大神果然是大神。 http://www.cnblogs.com/artech/archive/2008/09/01/1280939.html

在使用AX2012 AIF服务的时候,有一个问题一直困扰着我,那就是访问权限的认证。

众所周知AX2012的权限认证是基于AD的,但有些客户端机器的AD账户,并没有AX2012的访问权限,甚至没有加入AD中(如PDA客户端)。

按照微软的最佳实践,应该使用声明账户和可信中介这样两样技术,来实现客户端-》WCF中间层(可信中介)-》AIF服务。这样做好处,是客户端不用加入AD中,并且可以将客户端登陆账户权限的管理,纳入到AX中。

如果使用AX2012的自定义服务,会在AOS中有多个数据契约和服务操作,如果一个一个再在WCF中间层去重复造轮子,有些麻烦。能不能将中间层进行简化成,只是将客户端请求转发给AIF,将AIF的响应返回给客户端呢?

答案肯定是可以的咯,不然我也不会写这篇文章。具体可以参考上面蒋金楠老师博文的链接。

1新建一个WCF类库程序,代码如下:

namespace MessageInterceptor

{

[ServiceContract]

public interface IIntercept

{

[OperationContract(Action ="*", ReplyAction="*")]

Message Intercept(Message request);

}

[ServiceBehavior(UseSynchronizationContext = false, AddressFilterMode = AddressFilterMode.Any)]

public class InterceptService : IIntercept

{

public System.ServiceModel.Channels.Message Intercept(System.ServiceModel.Channels.Message request)

{


using (ChannelFactory<IIntercept> channelFactory = new
ChannelFactory<IIntercept>("calculateService"))

{

IIntercept interceptor = channelFactory.CreateChannel();

using (interceptor as IDisposable)

{

MessageBuffer requstBuffer = request.CreateBufferedCopy(int.MaxValue);

Message response = interceptor.Intercept(requstBuffer.CreateMessage());

MessageBuffer responseBuffer = response.CreateBufferedCopy(int.MaxValue);

Console.WriteLine(string.Format("Request:{0}{1}{0}", Environment.NewLine, request));

Console.WriteLine(string.Format("Response:{0}{1}{0}", Environment.NewLine, response));

return responseBuffer.CreateMessage();

}

}

}

}

}

该数据契约有以下两个特点:

  • Intercept的参数和返回值都是Message对象。
  • Operation的Action和ReplyAction为*。

无论参数的个数,类型,次序是怎样的,但WCF的调用最终是基于Message的,也就是参数或返回值最终都会呈现为Message对象。

Operation Selection的匹配规则是:Contract Namespace(default:http://tempuri.org)/Contract Name(default:Interface name)/Action(default:method name)= action in SOAP header。如果将Action设为"*",则意味着该服务的调用,无路SOAP Header中action是什么,都将交付Intercept来处理。

ChannelFactory构造函数的参数,是配置中,Client节点的endpoint的name值。

AddressFilterMode = AddressFilterMode.Any:在上面我们提到过,ChannelDispatcher在选择EndpointDispacher的时候是基于两个Message Filter:Address Filter和Contract Filter。也就是说,ChannelDispatcher通过这两个Filter选择合适Endpoint。在默认的情况下,Address Filter是根据SOAP的To Message Header的URI来进行栓选的,所以需要Endpoint的Address和To Header中的Addres完全匹配。但是在我们CalculateService的例子中,由于Client最终是访问的时CalculateService,所以生成的SOAP的To Headler的地址是CalculateService的地址:http://127.0.0.1:9999/calculateservice,而我们需要是用InterceptService 来处理该请求,Address Filtering肯定是不能通过的。好在我们可以在ServiceBehavior设置AddressFilterMode 来改变Address Filtering的方式。AddressFilterMode = AddressFilterMode.Any意味着,Address Filtering会被忽略。

CreateBufferedCopy:可能有人会奇怪,为什么不对request message和response message进行直接操作(将他们显示在TextBox上)?这是应为Message在WCF有一个特殊的处理机制:只有Message的State为Created的时候,才能获取MessageBody的内容,否则会抛出异常。而我们在对Message进行相应操作的时候,会改变Message 的State(Read,Written,Copied,Closed)。所以对response message来讲,对message的显示实际上将Sate改为Read,如何将response message直接返回到client,对该message的读取操作将是不允许的,所以先调用CreateBufferedCopy创建该message的一个memory buffer,最有返回的时通过该buffer重新创建的Message。

2新建Windows服务,作为上面WCF服务的宿主程序。

代码如下:

namespace MiddleTierWcfWindowsService

{

public partial class Service : ServiceBase

{

ServiceHost host;

public Service()

{

InitializeComponent();

}

protected override void OnStart(string[] args)

{

host = new ServiceHost(typeof(MessageInterceptor.InterceptService));

host.Open();

}

protected override void OnStop()

{

host.Close();

}

}

}

3为Windows服务添加应用程序配置App.config

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<system.serviceModel>

<bindings>

<netTcpBinding>

<binding name="aaaaaaaaa" />

</netTcpBinding>

</bindings>

<client>

<endpoint address="net.tcp://bbbbbbbbb"

binding="netTcpBinding" bindingConfiguration="aaaaaaaaa"

contract="eeeeeeeee" name="ccccccccc">

</endpoint>

</client>

<services>

<service name="HHHHHHHHH">

<endpoint binding="netTcpBinding" bindingConfiguration="aaaaaaaaa"

contract="eeeeeeeee"

address="net.tcp://ddddddddd"/>

</service>

</services>

</system.serviceModel>

</configuration>

AAAAAAAAA:这里我使用了NetTcpBinding,作为客户端-》WCF中间层(可信中介)-》AIF服务端的终结点的binding,你也可以选择适合自己的。

BBBBBBBBB:这里是AIF中,服务的URI。

CCCCCCCCC:这里是上面WCF中间层类库接口的实现中,ChannelFactory构造函数的参数,本例中是calculateService。

DDDDDDDDD:这里是WCF中间层的终结点地址。

EEEEEEEEE:是client和service的contract契约,都使用的是WCF中间层类库中的接口的"命名空间+接口名"。本例子中是MessageInterceptor.IIntercept。

HHHHHHHHH:是接口的实现。本例中是MessageInterceptor.InterceptService 。

4设置Windows服务的Service设计视图的ServiceName,用于在日志中显示。

5在Windows服务的Service设计视图上点右键,添加安装程序。

6在新添加的安装程序中,将serviceProcessInstaller1的Account设为LocalService。即,启动时,以本地服务方式登录。

7将serviceInstaller1的Description,DisplayName,ServiceName,都设置下,用于在系统服务中显示。

8安装生成的服务。

9在系统服务中,找到该服务,右键,属性,登录,登录为AX中的系统服务账户,如BC账户,密码为BC账户的密码。

10客户端的配置文件里,新增一个终结点行为。

<system.serviceModel>

<behaviors>

<endpointBehaviors>

<behavior name="FFFFFFFFF">

<clientVia viaUri="net.tcp://DDDDDDDDD" />

</behavior>

</endpointBehaviors>

</behaviors>

<bindings>

<netTcpBinding>

<binding name="AAAAAAAAA" />

</netTcpBinding>

</bindings>

<client>

<endpoint address="net.tcp://BBBBBBBBB"

behaviorConfiguration="FFFFFFFFF"

binding="netTcpBinding" bindingConfiguration="AAAAAAAAA"

contract="GGGGGGGGG" name="CCCCCCCCC">

</endpoint>

</client>

</system.serviceModel>

A、B、C、D、如上面所述。

FFFFFFFFF:终结点行为的名称。

GGGGGGGGG:AIF服务中,"命名空间+数据契约"的名字。本例为,MessageInterceptor.ICalculate

11结束

至此,WCF中间层的转发,已经设置好了。

在客户端,可以以context.LogonAsUser=aaa@bbb.com;的方法,用AX中的账户进行操作,系统会检查该账户的数据权限。在表中,记录的createdBy等系统字段,会显示为该AD用户的别名。

如果使用客户端的人员为一线工人,可能没有AX账户,所以此处建议不设置。表中的createdBy等系统字段,记录是BC账户的别名,使用的是BC的数据权限。

Dynamics AX 2012 R2 Service Middle Tier WCF WCF转发的更多相关文章

  1. Dynamics AX 2012 R2 电子邮件广播错误 0x80040213

    Dynamics AX 2012 R2 电子邮件广播错误 0x80040213 今天Reinhard在新环境做邮件广播测试时,发现无法发送邮件,并报以下错误: 类"CDO.Message&q ...

  2. Dynamics AX 2012 R2 安装Reporting Services 扩展

    今天Reinhard在VS中部署SSRS报表时,接到以下错误: 部署因错误而被取消.在报表服务器上,验证:-SQL Server Reporting Services 服务是否正在运行. 接着,Rei ...

  3. Dynamics AX 2012 R2 如何处理运行时间较长的报表

    当处理的数据量较多,逻辑比较复杂时,报表可能会超时.为了解决这个问题,Reinhard一直使用SrsReportDataProviderPreProcess来做预处理报表.它会在调用SSRS前,在AX ...

  4. Dynamics AX 2012 R2 安装额外的AOS

    众所周知,AX系统分为三层:Client,Application Server,Database Server. 我们添加额外的Application Server主要是出于以下两个原因: 使用多台服 ...

  5. Dynamics AX 2012 R2 业务系列-销售业务流程

    在博文Dynamics AX R2 业务系列中,Reinhard对这个系列做了一个规划,下面我们就按照规划开始说业务吧. 1.销售的主要职责 其实这里说的职责主要是针对销售文员,并非整天外面满世界跑业 ...

  6. Dynamics AX 2012 R2 业务系列-采购业务流程

    在博文Dynamics AX R2 业务系列中,Reinhard对这个系列做了一个规划,下面我们就按照规划开始说业务吧. 国际惯例,从采购开始. 1.采购的主要职责 简单点说,采购的主要职责,是从供应 ...

  7. Dynamics AX 2012 R2 安装 AIF IIS上的Web服务

    1.为什么使用IIS上的WEB服务 组件? 如果你要在Dynamics AX Service中使用HTTP Adapter,那么你就要安装IIS上的WEB服务 组件.HTTP Adapter会在IIS ...

  8. Dynamics AX 2012 R2 业务系列

    在之前的一系列博文里,Reinhard介绍了Dynamics AX Demo的安装与配置.相信同学们看完后,都已经成功拥有了一个测试环境. 众所周知的是,ERP作为一个特殊的软件系统,他有着背后的业务 ...

  9. [译]Dynamics AX 2012 R2 BI系列-规划分析的注意事项

    https://msdn.microsoft.com/en-us/library/gg731898.aspx       在开始实施AX的分析特性前,有很多事情要考虑.本文描述了你必须考虑的事情,和在 ...

随机推荐

  1. struts标签小记

    1.<s:iterator>标签的  奇偶数行使用不同样式 <s:iterator id="list" value="#request.listq&qu ...

  2. 【转】Tomcat组件生命周期管理

    Tomcat组件生命周期管理 Tomcat中Server,Service,Connector,Engine,Host,Context,它们都实现了org.apache.catalina.Lifecyc ...

  3. 示sudo: cd: command not found

    执行sudo cd 时出现 sudo: cd: command not found 原因shell shell是一个命令解析器 所谓shell是一个交互式的应用程序. shell执行外部命令的 时候, ...

  4. PostgreSQL Insight Monitor pgstat

    PostgreSQL Insight Monitor  pgstat pgstat 是一个连接到数据库并获取数据库的活动状态的命令行工具. PostgreSQL有许多状态: archiver for ...

  5. PostgreSQL Partitions

    why we need partitions The first and most demanding reason to use partitions in a database is to inc ...

  6. Leetcode: Frog Jump

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

  7. G面经prepare: Friends Recommendation

    想想如果你用linkedin或者facebook, 给你一个人和他的朋友关系网,你会怎么给一个人推荐朋友 一个例子就是A-B, A-C, B - D, B - E, C - D,这个时候问我应该推荐谁 ...

  8. spring 官方下载地址

    SPRING官方网站改版后,建议都是通过Maven和Gradle下载,对不使用Maven和Gradle开发项目的,下载就非常麻烦. 下给出Spring Framework jar官方直接下载路径: h ...

  9. struts2 标签为简单标签

    <s:form method="post" action="" theme="simple"> <s:textfield ...

  10. hduoj 4706 Children&#39;s Day 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4706 Children's Day Time Limit: 2000/1000 MS (Java/Others) ...