C# 将多个 Web 引用添加到同一 3rd 方 API 的不同版本时出现问题?

发布于 2024-11-19 12:38:39 字数 4839 浏览 2 评论 0原文

我的 C# ASP.NET MVC Web 应用程序遇到问题,我们试图添加对不同版本的 Magento API 的多个引用。

基本上我的应用程序需要能够连接到不同的 Magento 电子商务商店。其中一些商店可能是 1.4 版本,一些可能是 1.5 版本,等等。为了处理这种情况,我添加了多个 Web 引用,每个版本一个:

  <applicationSettings>
    <WebApp.Properties.Settings>
      <setting name="WebApp_MagentoWebReference_MagentoService"
        serializeAs="String">
        <value>http://example.com/magento1411/index.php/api/v2_soap/index/</value>
      </setting>
      <setting name="WebApp_Magento1510WebReference_MagentoService"
        serializeAs="String">
        <value>http://example.com/magento1510/index.php/api/v2_soap/index/</value>
      </setting>
    </WebApp.Properties.Settings>
  </applicationSettings>

然后在代码中,我确保使用与我的目标版本匹配的正确 Web 引用创建一个实例:

string url = "http://example.com/magento1411/index.php/api/v2_soap/";
_magentoService = new MagentoWebReference.MagentoService();
_magentoService.Url = url;
string apiUser = "user";
string apiKey = "key";
sessionId = _magentoService.login(apiUser, apiKey); 

var magentoProductList = _magentoService.catalogProductList(sessionId, null, null);

您可以看到我是故意的从版本 1.4 商店请求产品列表时创建版本 1.4 Web 参考。但是,当此代码运行时,它会失败并出现以下错误:

Cannot assign object of type WebApp.Magento1510WebReference.salesOrderInvoiceEntity[] 
to an object of type WebApp.MagentoWebReference.salesOrderInvoiceEntity[].

由于某种原因,返回值的类型为 Magento1510WebReference.salesOrderInvoiceEntity

像这样添加多个网络引用是否存在任何已知问题? Visual Studio 或 IIS 是否对这两个引用感到困惑?

这是完整的堆栈跟踪:

System.Exception: There was a problem recieving a list of invoices from mageto store: http://example.com ---> System.InvalidOperationException: There is an error in XML document (2, 485). ---> System.InvalidCastException: Cannot assign object of type WebApp.Magento1510WebReference.salesOrderInvoiceEntity[] to an object of type WebApp.MagentoWebReference.salesOrderInvoiceEntity[].
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read351_salesOrderInvoiceListResponse()
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer469.Deserialize(XmlSerializationReader reader)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at WebApp.MagentoWebReference.MagentoService.salesOrderInvoiceList(String sessionId, filters filters) in C:\src\WebApp.2010\WebApp.UI\Web References\MagentoWebReference\Reference.cs:line 3073
   at WebApp.Controllers.Magento.MagentoController.GetLatestInvoices() in C:\src\WebApp.2010\WebApp.UI\Controllers\Magento\MagentoController.cs:line 217
   --- End of inner exception stack trace ---

我可以看到,当从 Magento API 返回响应时,XmlSerializer.Deserialize 变得很困惑,并认为 XML 来自 Magento 1.5 参考,而不是 Magento 1.4 参考。问题是为什么会这样做,以及如何解决它?

编辑:

正如我怀疑 Magento API 响应的肥皂信封实际上对于两个版本来说是相同的:

1.4.1 soap = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:loginResponse><loginReturn xsi:type="xsd:string">6325f7753ea72ba70e0a04254d58abe5</loginReturn></ns1:loginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
1.5.1 soap = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:loginResponse><loginReturn xsi:type="xsd:string">90ebce956623bb7e1637165306de40d0</loginReturn></ns1:loginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

这意味着当收到响应时,Xml 反序列化器无法确定要使用哪个 Web 引用,因为它们都匹配响应签名。它最终使用 Magento1510 引用进行反序列化,而它应该是 Magento1411 引用。我能做些什么吗? (我已经开始尝试建议将参考文献分成单独的项目的答案)

I have a problem in my C# ASP.NET MVC web app where we are trying to add multiple references to different versions of the Magento API.

Basically my app needs to be able to connect to different Magento ecommerce stores. Some of these stores could be version 1.4, some could be 1.5 and so on. To handle this situation I have added multiple web references, one for each of the versions:

  <applicationSettings>
    <WebApp.Properties.Settings>
      <setting name="WebApp_MagentoWebReference_MagentoService"
        serializeAs="String">
        <value>http://example.com/magento1411/index.php/api/v2_soap/index/</value>
      </setting>
      <setting name="WebApp_Magento1510WebReference_MagentoService"
        serializeAs="String">
        <value>http://example.com/magento1510/index.php/api/v2_soap/index/</value>
      </setting>
    </WebApp.Properties.Settings>
  </applicationSettings>

And then in the code I make sure to create an instance using the right web reference that matches the version I am targeting:

string url = "http://example.com/magento1411/index.php/api/v2_soap/";
_magentoService = new MagentoWebReference.MagentoService();
_magentoService.Url = url;
string apiUser = "user";
string apiKey = "key";
sessionId = _magentoService.login(apiUser, apiKey); 

var magentoProductList = _magentoService.catalogProductList(sessionId, null, null);

You can see that I am deliberately creating the version 1.4 web reference when requesting the product list from a version 1.4 shop. However when this code runs it fails with this error:

Cannot assign object of type WebApp.Magento1510WebReference.salesOrderInvoiceEntity[] 
to an object of type WebApp.MagentoWebReference.salesOrderInvoiceEntity[].

For some reason the return value is of type Magento1510WebReference.salesOrderInvoiceEntity.

Is there any known problem adding multiple web references like this? Is Visual Studio or IIS getting confused between the two references?

This is the full stack trace:

System.Exception: There was a problem recieving a list of invoices from mageto store: http://example.com ---> System.InvalidOperationException: There is an error in XML document (2, 485). ---> System.InvalidCastException: Cannot assign object of type WebApp.Magento1510WebReference.salesOrderInvoiceEntity[] to an object of type WebApp.MagentoWebReference.salesOrderInvoiceEntity[].
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read351_salesOrderInvoiceListResponse()
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer469.Deserialize(XmlSerializationReader reader)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at WebApp.MagentoWebReference.MagentoService.salesOrderInvoiceList(String sessionId, filters filters) in C:\src\WebApp.2010\WebApp.UI\Web References\MagentoWebReference\Reference.cs:line 3073
   at WebApp.Controllers.Magento.MagentoController.GetLatestInvoices() in C:\src\WebApp.2010\WebApp.UI\Controllers\Magento\MagentoController.cs:line 217
   --- End of inner exception stack trace ---

I can see that when the response comes back from the Magento API that the XmlSerializer.Deserialize is getting confused and thinks that the XML comes from the Magento 1.5 reference, not the Magento 1.4 reference. The question is why does it do this, and how can it be fixed?

EDIT:

As I suspected the soap envelope of the response from the Magento API is actually the same for both versions:

1.4.1 soap = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:loginResponse><loginReturn xsi:type="xsd:string">6325f7753ea72ba70e0a04254d58abe5</loginReturn></ns1:loginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
1.5.1 soap = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:loginResponse><loginReturn xsi:type="xsd:string">90ebce956623bb7e1637165306de40d0</loginReturn></ns1:loginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

Which means that when the response is received, the Xml Deserializer cannot work out which of the web references to use because both of them match the response signature. And it ends up using the Magento1510 reference to deserialize, when it should have been the Magento1411 reference. Is there anything I can do about this? (I have started trying out the answer that suggests to split the references into separate projects)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三生路 2024-11-26 12:38:39

如果 WCF 服务的版本控制良好,即使您使用 1.5 程序集,您也应该能够与 1.4 版本进行交互。你试过这个吗?

如果这不起作用,我认为您需要将每个版本的代理分离到一个新项目中。这样您可以确保代理只知道当前版本,并且可以避免命名空间冲突。

If the WCF service is versioned in a good way you should be able to talk with the 1.4 version even if you use the 1.5 assemblies. Have you tried this?

If that doesn't work I think you need to seperate the proxy for each version into a new project. This way you can make sure the proxy only knows about the current version and you can avoid the namespace conflicts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文