.NET 2 ASMX Web 服务 - 通过 .NET 3.5 服务调用调用 - 公共类重用
我有一个带有单个 Web 方法的 .NET 2 Web 服务,如下所示:
[WebMethod]
public Common.foobar DoSomething(Common.foobar foo)
foobar 类是在通用 .NET 2 程序集中定义的,该程序集也可用于调用 .NET 3.5 应用程序(作为项目引用)通过服务引用(不是 .NET 兼容性 Web 引用)的 Web 服务。
问题是服务引用命名空间包含它自己的、自动生成的 foobar 实现。因此,在代理 SOAP 客户端上可用的自动生成的服务引用方法具有以下签名:
ServiceReference.foobar DoSomething(ServiceReference.foobar foo)
稍微谷歌搜索一下,我就会发现这是不可避免的,因为 Web 服务是基于 .NET 2 的,因此不支持公共类的重用。在WCF中。
所以问题是:有人知道一种简单可靠的方法将 Common.foobar 类克隆到 WebServiceReference.foobar 类中吗?或者有人知道我可以使用公共库中定义的类的“黑客”吗?另外,任何人都可以指出我在哪里错过了树木,事实上可以使用公共库类
编辑 - 一些更多信息
.NET 2 webservice 类看起来像这样:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public CommonLibrary.Foobar DoSomething(CommonLibrary.Foobar foo)
{
return new CommonLibrary.Foobar() { Data = "Data in common foobar class", EventCode = 1, MessageId = "mid" };
}
}
调用客户端(.NET 3.5 - 带有对 .NET 服务的服务引用)看起来像这样:
static void Main(string[] args)
{
// Create the soap client for the .NET 2 service using the auto generated proxy class
var serviceClient = new NET2WebService_ServiceReference.Service1SoapClient();
//Just checking that there is a project reference to CommonLibrary
var commonFoobar_Request = new CommonLibrary.Foobar()
{
Data = "Common foobar data",
EventCode = 1,
MessageId = "Common foobar message id"
};
// This doesn't work as the Service Reference client does not accept the
// common foobar class.
/*
var commonFoobar_Response = serviceClient.DoSomething(commonFoobar_Request);
Console.WriteLine(commonFoobar_Response.Data);
*/
// This is the proxy class to foobar generated by the Service Reference
var serviceRefFoobar_Request = new NET2WebService_ServiceReference.Foobar()
{
Data = "Common foobar data",
EventCode = 1,
MessageId = "Common foobar message id"
};
// This does work as it does uses the autogenerated Foobar class in the service
// reference
var serviceRefFoobar_Response = serviceClient.DoSomething(serviceRefFoobar_Request);
Console.WriteLine(serviceRefFoobar_Response.Data);
}
公共库(也是 .NET 2)中的 foobar 类看起来像这样:
public partial class Foobar
{
private string dataField;
private int eventCodeField;
private string messageIdField;
public string Data
{
get
{
return this.dataField;
}
set
{
this.dataField = value;
}
}
public int EventCode
{
get
{
return this.eventCodeField;
}
set
{
this.eventCodeField = value;
}
}
public string MessageId
{
get
{
return this.messageIdField;
}
set
{
this.messageIdField = value;
}
}
}
并且派生自一个架构,该架构如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Foobar">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Data" type="xs:string"/>
<xs:element name="EventCode" type="xs:int"/>
</xs:sequence>
<xs:attribute name="MessageId" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
最后,这是 .NET 3.5 客户端上的服务参考配置页面的屏幕截图:
您可以从该屏幕截图中看到,服务配置(以及客户端项目)知道包含我的 Foobar 类实现的 CommonLibrary。
值得一提的是,上面发布的所有内容都有效,但实际上 foobar 类比此处发布的示例要复杂得多。因此,我渴望找到一个可以在整个框架中使用 Common.foobar 的解决方案,而不必翻译 Common.Foobar => 。 ServiceReference.Foobar 用于请求,反之亦然用于响应。
I have a .NET 2 web service with a single web method that looks something like this:
[WebMethod]
public Common.foobar DoSomething(Common.foobar foo)
The foobar class is defined in a common .NET 2 assembly that is also available (as a project reference) to a .NET 3.5 application that calls the webservice via a Service Reference (not a .NET compatibility web reference).
The issue is that the service reference namespace contains its own, auto generated, implementation of foobar. So the auto generated Service Reference method, available on the proxy SOAP client, has the following signature:
ServiceReference.foobar DoSomething(ServiceReference.foobar foo)
A little googling tell me that this is unavoidable as the web service is .NET 2 based and therefore reuse of common classes is not supported as it is in WCF.
So the question is: does anybody know of a simple and reliable way to clone a Common.foobar class into a WebServiceReference.foobar class? Alternatively does anybody know of a "hack" where I can use the class as defined in the Common library? Alternatively can anybody point out where I have missed the wood for the trees and it is infact possible to use the Common library class
EDIT - Some more information
The .NET 2 webservice class looks like this:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public CommonLibrary.Foobar DoSomething(CommonLibrary.Foobar foo)
{
return new CommonLibrary.Foobar() { Data = "Data in common foobar class", EventCode = 1, MessageId = "mid" };
}
}
The invoking client (.NET 3.5 - With a Service Reference to the .NET service) looks like this:
static void Main(string[] args)
{
// Create the soap client for the .NET 2 service using the auto generated proxy class
var serviceClient = new NET2WebService_ServiceReference.Service1SoapClient();
//Just checking that there is a project reference to CommonLibrary
var commonFoobar_Request = new CommonLibrary.Foobar()
{
Data = "Common foobar data",
EventCode = 1,
MessageId = "Common foobar message id"
};
// This doesn't work as the Service Reference client does not accept the
// common foobar class.
/*
var commonFoobar_Response = serviceClient.DoSomething(commonFoobar_Request);
Console.WriteLine(commonFoobar_Response.Data);
*/
// This is the proxy class to foobar generated by the Service Reference
var serviceRefFoobar_Request = new NET2WebService_ServiceReference.Foobar()
{
Data = "Common foobar data",
EventCode = 1,
MessageId = "Common foobar message id"
};
// This does work as it does uses the autogenerated Foobar class in the service
// reference
var serviceRefFoobar_Response = serviceClient.DoSomething(serviceRefFoobar_Request);
Console.WriteLine(serviceRefFoobar_Response.Data);
}
The foobar class in the common library (also .NET 2) looks like this:
public partial class Foobar
{
private string dataField;
private int eventCodeField;
private string messageIdField;
public string Data
{
get
{
return this.dataField;
}
set
{
this.dataField = value;
}
}
public int EventCode
{
get
{
return this.eventCodeField;
}
set
{
this.eventCodeField = value;
}
}
public string MessageId
{
get
{
return this.messageIdField;
}
set
{
this.messageIdField = value;
}
}
}
And is derived from a schema that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Foobar">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Data" type="xs:string"/>
<xs:element name="EventCode" type="xs:int"/>
</xs:sequence>
<xs:attribute name="MessageId" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
And finally, here is a screenshot of the Service Reference configuration page on the .NET 3.5 client:
You can see from that screenshot that the Service Configuration, and therefore the client project, is aware of the CommonLibrary that contains my implementation of the Foobar class.
It is worth mentioning that everything posted above works, however in reality the foobar class is far more complicated that the sample posted here. Therefore I am keen to find a solution where I can use Common.foobar throughout the entire framework rather than having to translate Common.Foobar => ServiceReference.Foobar for requests and vice versa for responses.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我读到的有关 ASMX Web 服务的所有内容都表明它们不支持在客户端重用类型的功能。仅当服务是 WCF 服务而不是旧版 ASMX 服务时,此功能才存在。
也许是因为 WCF 使用差异序列化器,但我不确定。
是否可以将您的 ASMX Web 服务转换为 WCF 服务?
Everything I have read about ASMX web services suggests that they do not support the functionality of reusing types on the client side. This functionality only exists when the service is a WCF service and not a legacy ASMX service.
Perhaps it’s because WCF uses a difference serializer, but I’m not sure.
Is it possible to convert your ASMX web service to as WCF service?
类的重用是客户端的功能,而不是服务器端的功能。如果您的客户端代码引用相同的程序集,并且在使用“添加服务引用”时启用共享,那么这可能会起作用。
The reuse of classes is a function of the client side, not the server side. If your client code references the same assembly, and if you enable sharing when you use "Add Service Reference", then this may work.