magento的.net c#环境下调用v2 soap接口时发现urn:Magento的associativeMultiArray错误解决

magento的.net c#环境下调用v2 soap接口时发现以下错误:
自定义工具错误: 无法导入 Web 服务/架构。无法从命名空间“urn:Magento”导入绑定“Mage_Api_Model_Server_V2_HandlerBinding”。 无法导入操作“catalogProductCreate”。 缺少数据类型“urn:Magento:associativeMultiArray”。
这是magento的一个bug
解决方法是:
/app/code/core/Mage/Api/etc/wdsl2.xml
中的某个complexType块的下方增加如下内容即可

<complexType name="associativeMultiArray">
                <all>
                    <element name="associativeArray" type="typens:associativeArray" minOccurs="0" />
                </all>
 </complexType>

用.net c#正式完成对magento zen-cart订单,客户资料混合同步到erp的功能

用.net c#正式完成对magento zen-cart订单,客户资料混合同步到erp的功能.
为什么叫混合同步呢?
zen-cart同步用的是对mysql中指定的数据库增量查询方式同步到本地的ms sql server中,然后到按指定格式进入勤哲excel的erp中.
magento主要用的是magento v2 soap webserver api的方式,将magento的相应数据按指定格式组织本地的ms sql server中,然后到按指定格式进入勤哲excel的erp中,同时也支持对magento使用的数据库按增量查询方式同步到本地.
同时用到两种同步渠道,对两种网店进行同步,所以说是混合同步.
既然能支持两种网店的同步,当然就有可能支持第三种,第四种.可惜我没那么多精力用这么网店,除了zen-cart,magento,其它就暂时不考虑了.不过其它网店只要用数据库增量查询方式同步就可以了.

.net c#成功通过勤哲excel模板向magengo提交订单帐单和运输相关信息

.net c#成功通过勤哲excle模板向magengo分别提交订单,帐单,运输相关信息,主要的使用的提交函数是以下(以下是php语法,.net语法与下类似)
sales_order_invoice.addComment – Add new comment to invoice
sales_order_invoice.capture – Capture invoice
sales_order_invoice.void – Void invoice
sales_order_invoice.cancel – Cancel invoice
sales_order_shipment.addComment – Add new comment to shipment
sales_order_shipment.addTrack – Add new tracking number
sales_order.addComment – Add comment to order
sales_order.hold – Hold order
sales_order.unhold – Unhold order
sales_order.cancel – Cancel order。
当然是在勤哲excle模板定义数据,然后通过同步软件向magento提交。

.net c#在使用magento v2 soap webserver时,如何将对象转换成datatable

.net c#在使用magento v2 soap webserver时,调用一些对象,如何将这些对象转换成datatable的数据表,以便能方便的通过update,直接保存到ms sql server数据库中,以下有个简便的方法,代码如下:

 /// <summary>
        /// 从指定的类中将数据转换成DataTable
        /// </summary>
        /// <param name="accessclass">类</param>
        /// <param name="tablename">表名</param>
        /// <param name="websitenumber">前缀</param>
        /// <returns></returns>
        public static DataTable GetClasstoTable(object accessclass, string tablename, string websitenumber)
        {
            System.Reflection.PropertyInfo[] ps = accessclass.GetType().GetProperties();

            DataTable dt = new DataTable();
            dt.TableName = tablename;
            dt.Columns.Add("website_number");

            foreach (System.Reflection.PropertyInfo pi in ps)
            {
                dt.Columns.Add(pi.Name);
            }

            DataRow dr = dt.NewRow();
            dr["website_number"] = websitenumber;
            foreach (System.Reflection.PropertyInfo pi in ps)
            {
                if (pi.PropertyType.Name == "String" || pi.PropertyType.Name == "Int") dr[pi.Name] = pi.GetValue(accessclass, null);
            }
            dt.Rows.Add(dr);

            //dt.WriteXmlSchema(tablename + ".xml");
            return dt;
        }

以下是调用示例:

   public int GetProductsData(MagentoRemoteAccess.MagentoService accessmagento, string magentologin, string webnumber)
        {
            Int64 MaxId = MsAccess.GetDataMaxId("magento_products", "product_id", "website_number", webnumber);
            MagentoRemoteAccess.filters magentofilter = AddFilter("product_id", "gt", MaxId.ToString());


            MagentoRemoteAccess.catalogProductEntity[] magentofind = accessmagento.catalogProductList(magentologin, magentofilter, "");


            int findrow = 0;
            foreach (MagentoRemoteAccess.catalogProductEntity tempfind in magentofind)
            {
                DataTable productstable = GetClasstoTable(tempfind, "magento_products", webnumber);

                MagentoRemoteAccess.catalogProductImageEntity[] testimage = accessmagento.catalogProductAttributeMediaList(magentologin, tempfind.sku, "default", "sku");
                foreach (MagentoRemoteAccess.catalogProductImageEntity imagesfind in testimage)
                {
                    DataTable stdatatTable = GetClasstoTable(imagesfind, "magento_productsimages", webnumber, "sku", tempfind.sku, "product_id", tempfind.product_id);
                    savedatatable(stdatatTable, "magento_productsimages");
                }
               
                savedatatable(productstable, "magento_products");

                findrow = findrow + 1;

            }
            if (findrow > 0) magentoisupdate = true;
            return findrow;

        }

其中savedatatable函数代码如下(这个函数用到了Enterprise Library 3.1 的功能,所以代码很简洁):

/// <summary>
        /// 将数据保存到表中
        /// </summary>
        /// <param name="savetabe">数据</param>
        /// <param name="tablename">表名</param>
        /// <returns></returns>
        private int savedatatable(DataTable savetabe, string tablename)
        {

            int allrow = 0;
            string query = "select * from " + tablename;
            string connectionstring = magentoDB.CreateConnection().ConnectionString;
            SqlConnection conn = new SqlConnection(connectionstring);
            conn.Open();
            SqlDataAdapter da = new SqlDataAdapter(query, conn);
            SqlCommandBuilder cb = new SqlCommandBuilder(da);

            try
            {
                allrow = da.Update(savetabe);

            }
            catch (SqlException e)
            {
                allrow = -1;
             }
            conn.Close();

            return allrow;

        }

这样就很容易的将magento对象获取的数据直接转移到ms sql server中,很方便的。

.net c#如何通过magento soap v2 webserver调用,进行filters设置,以便能过滤条件

magento soap v2 webserver中有很多对象在获取数据时,可以根据指定的条件进行过滤,如:salesOrderList,catalogProductList,customerCustomerList等,但是语法是什么样的,找了半天magento官方的的资料,也没有特别针对.net c#的语法操作,php的示例倒是一堆,以下是我自己做的可以用的代码示例。
首先建一个函数,用于组装filter.

 public MagentoRemoteAccess.filters  AddFilter( string name, string comparer, string comparisonVal)
        {
             MagentoRemoteAccess.filters tempfilter = new GetMySqlData.MagentoRemoteAccess.filters();

            MagentoRemoteAccess.associativeEntity ent = new MagentoRemoteAccess.associativeEntity();
            ent.key = comparer;
            ent.value = comparisonVal;

            MagentoRemoteAccess.complexFilter filter = new MagentoRemoteAccess.complexFilter();
            filter.key = name;
            filter.value = ent;

            MagentoRemoteAccess.complexFilter[] filters=new GetMySqlData.MagentoRemoteAccess.complexFilter[1];
            filters[0] = filter;
            tempfilter.complex_filter = filters;
           
            return tempfilter;
        }
 

调用语法如下:
MagentoRemoteAccess.filters magentofilter = AddFilter("order_id", "gt", 64);
意思如下:where order_id>64,为什么是>呢,gt就是>的意思,magento就是这样表示的。其它的符号意思如下:
eq  =
neq !=
like  link
nlike  not like
is is
in in
nin not in
notnull is not NULL
null is NUll
gt >
lt <
gteq >=
moreq >=
lteq <=
finset  find_in_set('n2510',e.suk)
from  to     >=  and <=
这些都是只单个条件,如果
上述函数中只要进行适当的改写,就可支持多个条件参数,这时多个条件参数的关系是and,or的关系如何组合呢,暂时没用就没研究了!

.net c#如何通过magento soap v2 webserver对象catalogProductInfo获取详细的产品信息

magento soap v2 webserver对象catalogProductInfo,在获取详细的产品信息需要的参数中有一个参数是catalogProductRequestAttributes,如果没有这个,获取的一些数据很多都是null,那这个参数要如何设置呢?
以下是示例,
1、设置好catalogProductRequestAttributes
    catalogProductRequestAttributes attrib = new catalogProductRequestAttributes();
    attrib.attributes = new string[] { “additional_attributes”, “website_number”, “product_id”, “sku”, “set”, “type”, “categories”, “websites”, “created_at”, “updated_at”, “type_id”, “name”, “description”, “short_description”, “weight”, “status”, “url_key”, “url_path”, “visibility”, “category_ids”, “website_ids”, “has_options”, “gift_message_available”, “price”, “special_price”, “special_from_date”, “special_to_date”, “tax_class_id”, “tier_price”, “meta_title”, “meta_keyword”, “meta_description”, “custom_design”, “custom_layout_update”, “options_container”, “additional_attributes”, “enable_googlecheckout” };

2、通过catalogProductInfo对象获取产品信息
catalogProductReturnEntity testproin = test11.catalogProductInfo(testlogin, temparrin.sku, “default”, attrib, “sku”);

注意,如何你选择上述catalogProductRequestAttributes中定义的值,会造成.net获取产品信息过慢的问题,你最好根据需要,有选择的设置catalogProductRequestAttributes中要提取的信息。

如何通过.net c#的soap v2 webserver获取多个magento网站的数据

.net c#的项目通过magento soap v2 webserver的服务,在项目内完成对magento服务的web引用,但如何要对多个magento网站群进行访问,难道要逐个在项目中生成web引用吗?显然这是一个不可取的方法。
解决方法如下:
1、首先在项目内针对一个magento网站建立完整的web引用,引用名定义为:MagentoRemoteAccess
2、将这个web引用的url行为改成动态
3、将这个web费用url的网站名换成无效,这时会提示出错,不管
4、通过以下代码,完成对指定magento网站的web引用:
    

MagentoRemoteAccess.MagentoService accessmagento = new MagentoRemoteAccess.MagentoService();
 accessmagento.Url = "http://" + website + "/index.php/api/v2_soap/index/";

这样就可以实现通过soap v2 webserver获取多个magento网站的数据
 

.net c#如何调用引用magento webservice api接口正确方法

magento webservice  api有两种接口,一种是soap,另外一种是v2_soap,从实际情况看,soap这种方式主要供php等之类使用,调用的webservice soap地址格式如下:

http://www.exampledomain.com/shop/index.php/api/soap/?wsdl
如果.net c# 使用这种格式,在调用login时就会出现如下错误:

客户端发现响应内容类型为“text/html”,但应为“text/xml”。请求失败

经过了解,原来java和.net使用magento webservice api soap的接口,用的是magento的v2_soap,地址调用格式如下:
http://www.exampledomain.com/shop/index.php/api/v2_soap/?wsdl

在soap中,调用相应的magento的api,用是的call方式调用相关的函数,
如:
$proxy->call($sessionId, ‘sales_order.info’, ‘100000003’));

而v2_soap中,java或.net,是直接调用相应的函数,
如:
proxy.salesOrderInfo(sessionId, “100000003”);

还是有区别的,大家不要误入岐途!