在.NET中处理coldfusion complex类型

时间:2011-12-08 12:31:11

标签: .net arrays web-services coldfusion

我尝试向.net webservice发送一个来自coldfusion的已定义组件数组,但是我得到一个错误,我不知道如何处理.net方法中的复杂类型。 我的组件是:

<cfcomponent name = "Person" output="false">
    <cfproperty name="name" type="string" />
    <cfproperty name="surname" type="string" />
</cfcomponent>

<cfset personArray = ArrayNew(1) />
<cfloop from="1" to="10" index="i">
    <cfset personArray[#i#] = createObject("component", "person")>
    <cfset personArray[#i#].name = "personname" />
    <cfset personArray[#i#].surname = "personsurname" />
</cfloop>

<cfscript>
     service = CreateObject("webservice", "service.asmx?WSDL");
     r = service.SendArray(#personArray#,0);
</cfscript>

.net中的方法如下所示:

public string SendArray(Object[] personList, int numberid)
{   
    ...
}

错误是消息内容:无法找到带参数{[[(Component = person)],...}的Web服务操作SendArray。如果我修改并调用没有复杂类型的方法SendArray(0),则方法被正确调用。我不知道如何在.net中定义和获取数组。

1 个答案:

答案 0 :(得分:3)

首先,一些语义错误:

您使用ArrayNew(1)创建了一个数组,但是您通过最后的干扰键隐式地将数组的每个索引强制转换为Struct,这会更改其类型(因为ColdFusion是动态类型的)。考虑:

<cfloop from="1" to="10" index="i">
    <cfset personArray[i] = StructNew() />
    <cfset personArray[i].object = createObject("component", "person")>
    <cfset personArray[i].name = "personname" />
    <cfset personArray[i].surname = "personsurname" />
</cfloop>

现在,personArray仍然是一个真正的数组,而不是在传递之前被强制转换为Struct。

然而,有一个更大的问题......

通过SOAP进行的Web服务消息传递不是为了便于支持从点到点传递复杂的业务对象;这是一种常见的误解,会让刚刚开始使用SOA的开发人员感到困惑和沮丧。这不是ColdFusion和/或.NET本身的问题 - 这是一个低级SOAP限制。

让我们假设有一种方法可以做你想做的事情,并且在上面的“人物”组件中,在ColdFusion的范围内,它作为一个具有自己的属性和方法的完整对象存在,其中涉及维护状态(例如,isPersonLoggedIn()),内部由ColdFusion中存在的功能管理(即自动处理CFID和CFTOKEN,访问共享SESSION范围等)< / p>

现在,如果您假设能够将登录的“Person”对象传递给.NET应用程序 - 然后,.NET应用程序决定在其末端调用isPersonLoggedIn() - 它怎么可能知道怎么做?它不了解CFID或CFTOKEN,没有共享内存的概念(或者至少,ColdFusion期望如何处理共享内存) - 并且没有任何东西可以通过线路转换这些概念,因为(当然)维护所述状态首先存在于CF服务器上ram的物理边界内。

虽然这是一个疯狂的类比,但它应该有一个更清晰的画面,说明为什么你不能做你想做的事情 - 通过一个机制传递一个复杂的业务对象,其中(在它的核心)是一个流XML。

当您开发基于SOAP的服务(消费者和生产者)时,您需要考虑简单的值:查找此用户的名称。给我这个员工的电话号码。告诉我这个数据库中有多少记录用于给定的部门ID。

与以下相反:采用这个业务对象代表我们可以在我们的应用程序范围内的“人员”上执行的所有功能,这是世界上没有其他应用程序知道的 - 并且神奇地将其交给任何应用程序和期望它以同样的方式行事。

拿走积分:

  1. 考虑重新考虑您的设计。而不是传递Person对象本身,设计方法只会根据person对象(即PersonID,PersonName,NumberOfPeople等)查找某些离散值。

  2. 请参阅this chart on data types for web-service communication in ColdFusion

  3. 否则,构建.NET服务的人会要求您提供许多预编译的类,这些类必须集成到最终,以便了解您的业务对象。 ..此时,您不再通过SOAP通过网络服务进行通信 - 您正在通过电话与他们的开发人员进行通信......每次单个业务对象发生变化时,您都必须重新编写代码。

    如需进一步阅读,请查看my answer someone on StackOverflow that asked the reverse of your question