我开发了一个Web服务,通过查询中央数据库来检查用户授权。每当用户启动它时,它应该被任何应用程序使用,以便检查是否允许用户运行该应用程序。 由于在公司中有许多用Visual Basic 6编写的旧应用程序由没有良好编程技能的人编写,我正在尝试创建一个他们可以在VB6应用程序中轻松使用的DLL,通过简单的函数调用来检查用户授权而不是处理Web服务调用和XML消息等细节。
我使用C#在Visual Studio 2010中创建了一个类库,只需包装Web服务功能。我成功创建了DLL文件并将其(通过RegAsm)注册到另一台用于开发Visual Basic 6应用程序的机器中。
在VB6中,intellisense显示DLL暴露的函数(可以调用),但它不适用于函数返回的复杂类型。
例如,DLL定义了以下函数,其中返回的类型(User
)被定义到Web服务代码中:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("AuthorLibrary.Author")]
[Guid("D2E23F5E-C209-464A-AF32-CC0251078076")]
//[ComDefaultInterface(typeof(IAuthor))]
public class Author //: AuthorLibrary.IAuthor
{
//[...]
public User getUserData(string username)
{
ResponseMessageOfUser user;
using (AccessControlSoapClient ws = new AccessControlSoapClient())
{
user = ws.getUserData(username);
}
if (user.response != ResponseType.Ok)
throw new Exception(user.response.ToString());
return user.result;
}
//[...]
}
在VB6中,以下代码正确运行:
Dim ws As AuthorLibrary.Author
Set ws = New AuthorLibrary.Author
Dim u As AuthorLibrary.User
Set u = ws.getUserData("john.smith")
Text1.Text = u.email
问题在于,当开发人员写u.
时,没有任何内容出现,因此他不知道对象的可用属性和/或方法(即使在上面的示例中u.email
有效)
另一种方法返回Department
的实例(让我们称之为dept
)。我可以成功打印简单string
属性的值,例如dept.Description
或dept.Code
,但更复杂的属性,例如dept.childrenDepartments
- 应返回Department
列表 - 给出错误:“缺少对象”。
我认为问题是 DLL文件没有显示定义到Web服务中的类/类型/结构。我怎么能这样做?
我还试图定义以下界面(IAuthor
,正如您从第一个代码中看到的那样),但它似乎不起作用:
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("DB3BA840-B997-4D5E-86F0-0FC0A786C0D3")]
interface IAuthor
{
//[...]
}
答案 0 :(得分:1)
[InterfaceType]属性确实是关键。如果未明确应用该属性,则默认值为ComInterfaceType.InterfaceIsIDispatch
。这只允许后期绑定,相当于在C#中调用 dynamic 类型的对象引用上的方法。请注意,如果没有获得IntelliSense,VB6程序员也会遇到同样的问题。
您尝试的IAuthor可能无法正常工作,因为您忘记将其公之于众。
所以你需要在User
类上获得该属性。您将遇到问题,因为您没有创建该类。因此,对于其中一个,您可能也不能轻易声明IUser接口。这方面的后果是在课堂上应用[ClassInterface(ClassInterfaceType.AutoDual)]
。它不是最漂亮的解决方案,也暴露了System.Object的成员,并为VB6程序员提供了对.NET Framework类型库的依赖,但这不是世界末日。但是,您仍然需要编辑类声明以应用该属性。
如果它是从Web服务生成的,那么您将面临维护问题。每次重新生成时,您都必须再次进行编辑。然后,这也很容易打破VB6代码,它必须重新编译。因此,您可能需要考虑隔离该声明,因此这不是必需的。声明您自己的User类并编写代码以将Web服务的User对象的字段/属性复制到您的用户对象。当然,编写接口和应用属性也不会有任何问题。