我正在尝试连接Magento(os commerce solution)提供的API WebService。
由于来自magento的这个web服务需要对每个方法进行会话处理(除login
和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生成的Proxy类:
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);
我无法弄清楚为什么会这样。使用静态方法和调用基类的方法有什么区别?
除此之外,消费magento webservice对于使用.NET的#*(使用v2 soap服务变得更好)是一种痛苦......
亲切的问候,
阿恩特
答案 0 :(得分:0)
我找到了答案,它的名字是愚蠢......
Magento允许在parentId
- 方法中使用空参数catalogCategoryTree
。
为了测试我的包装器类,我构建了一个简单的表单,它将parentId
和storeView
参数传递给`catalogCategoryTree-method。但是,当没有输入任何内容时,我传递空字符串文字(文本字段的值)。然后发生错误......
我上面发布的工作静态测试方法丢弃了parentId
和storeView
- 参数,并将null
传递给了magento API,magento显然可以处理。因此,Magento在null参数(至少对于字符串)和空字符串之间有所不同。
如果我重写我自己的catalogCategoryTree
方法来检查空字符串,一切都按计划工作......
public MagentoService.catalogCategoryTree catalogCategoryTree(string parentId, string storeView)
{
parentId = (string.IsNullOrEmpty(parentId)) ? null : parentId;
storeView = (string.IsNullOrEmpty(storeView)) ? null : storeView;
return base.catalogCategoryTree(sessionId, parentId, storeView);
}