我正在尝试连接 Magento(os 商务解决方案)提供的 API WebService。
由于来自 magento 的这个 web 服务需要为每个方法(除了login
and endSession
)进行会话处理,我想将生成的 WCF 代理类包装在我自己的类中,做所有的会话处理工作。
但是,我一生都无法弄清楚为什么我的派生类与我派生的原始 WCF 包装器的工作方式不同。特别是长时间运行的方法会失败(使用此堆栈跟踪:
System.ServiceModel.FaultException: Internal Error. Please see log for details.
Server stack trace:
bei System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
bei System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
bei System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
这是我的包装类的(初稿)(MagentoService 是 Magento Webservice 的生成代理类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace MagentoConnector
{
public class MagentoController : MagentoService.Mage_Api_Model_Server_V2_HandlerPortTypeClient
{
private string username = "apiusername";
private string password = "apiuserpassword";
private string sessionId = null;
public MagentoController(string url) : base()
{
if(!string.IsNullOrEmpty(url)) {
if(!url.ToLower().StartsWith("http://")) url = "http://" + url;
if(!url.EndsWith("/")) url += "/";
url += "magento/index.php/api/v2_soap/index/";
this.Endpoint.Address = new EndpointAddress(new Uri(url), this.Endpoint.Address.Identity, this.Endpoint.Address.Headers);
}
this.Open();
}
public MagentoController(string url, string username, string password) : this(url)
{
if(!string.IsNullOrEmpty(username)) {
this.username = username;
}
if(!string.IsNullOrEmpty(password)) {
this.password = password;
}
sessionId = this.login(this.username, this.password);
}
public new string login(string username, string password)
{
if(!string.IsNullOrEmpty(sessionId)) {
this.endSession(sessionId);
}
sessionId = base.login(username, password);
this.username = username;
this.password = password;
return sessionId;
}
public string login()
{
return login(this.username, this.password);
}
public void logoff()
{
if(!string.IsNullOrEmpty(sessionId)) {
this.endSession(sessionId);
}
}
~MagentoController()
{
try {
logoff();
} catch(Exception) {
;
}
}
public MagentoService.catalogCategoryTree catalogCategoryTree(string parentId, string storeView)
{
return base.catalogCategoryTree(sessionId, parentId, storeView);
}
public static MagentoService.catalogCategoryTree getCatalogTree(string parentId, string storeView)
{
string sessionId = null;
MagentoService.catalogCategoryTree myTree = null;
MagentoService.Mage_Api_Model_Server_V2_HandlerPortTypeClient myService = new MagentoService.Mage_Api_Model_Server_V2_HandlerPortTypeClient();
try {
myService.Open();
sessionId = myService.login("applus-dev", "FL1LBveiNW8nGOg9QRa4z");
myTree = myService.catalogCategoryTree(sessionId, null, null);
} finally {
if(myService != null && !string.IsNullOrEmpty(sessionId)) {
myService.endSession(sessionId);
}
}
return myTree;
}
}
}
请注意静态方法getCatalogTree
,它直接与 接口MagentoService
,并按其应有的方式工作(返回 magento 的所有类别节点的树)。该方法catalogCategoryTree
在调用基本方法时失败,并出现上述错误。
这是调用代码:
MagentoController myService = new MagentoController(null, null, null);
MagentoService.catalogCategoryTree myTree = myService.catalogCategoryTree(parentId, storeView);
我无法弄清楚为什么会这样。使用静态方法和调用基类的方法有什么区别?
除此之外,使用 .NET 的 a#*(使用 v2 soap 服务变得更好)使用 magento 网络服务是一件痛苦的事情......
亲切的问候,
阿恩特