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>

magento的soap v2接口在.net c#调用时出现响应text/html,应为text/xml的错误解决

magento在.net c#调用v2 soap接口时,在login验证时,出现,“客户端发现响应内容类型为“text/html”,但应为“text/xml”。\r\n请求失败,错误信息为:\r\n–\r\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n                <SOAP-ENV:Body>\n                <SOAP-ENV:Fault>\n                <faultcode>0</faultcode>\n ”
的错误。
经过排查,是没有安装php-soap插件引用的
在centos环境下yum -y install php-soap即可完全安装。

用C#通过ebay api的GetOrders获取订单的示范代码

关天getorders的功能的官方说明

http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/GetOrders.html

web的引用地址:http://developer.ebay.com/webservices/latest/eBaySvc.wsdl

另外一个vb.net的getorders示范代码https://ebay.custhelp.com/app/answers/detail/a_id/505/~/getorders-sample-in-vb.net-using-ebay-sdk-v459.0-for-.net

using eBay.Service.Call;
using eBay.Service.Core.Sdk;
using eBay.Service.Util;
using eBay.Service.Core.Soap;

namespace Trading_Samples
{
public class OrderManagement
{
//GetOrders
private void GetOrders()
{
//create the context
ApiContext context = new ApiContext();

//set the User token
context.ApiCredential.eBayToken = “Your token”;

//set the server url
context.SoapApiServerUrl = “https://api.sandbox.ebay.com/wsapi”;

//enable logging
context.ApiLogManager = new ApiLogManager();
context.ApiLogManager.ApiLoggerList.Add(new FileLogger(“log.txt”, true, true, true));
context.ApiLogManager.EnableLogging = true;

//set the version
context.Version = “705”;
context.Site = SiteCodeType.UK;
bool blnHasMore = true;

DateTime CreateTimeFromPrev, CreateTimeFrom, CreateTimeTo;

GetOrdersCall getOrders = new GetOrdersCall(context);
getOrders.DetailLevelList = new DetailLevelCodeTypeCollection();
getOrders.DetailLevelList.Add(DetailLevelCodeType.ReturnAll);

//CreateTimeTo set to the current time
CreateTimeTo = DateTime.Now.ToUniversalTime();

//Assumption call is made every 15 sec. So CreateTimeFrom of last call was 15 mins
//prior to now
TimeSpan ts1 = new TimeSpan(9000000000);
CreateTimeFromPrev = CreateTimeTo.Subtract(ts1);

//Set the CreateTimeFrom the last time you made the call minus 2 minutes
TimeSpan ts2 = new TimeSpan(1200000000);
CreateTimeFrom = CreateTimeFromPrev.Subtract(ts2);

getOrders.CreateTimeFrom = CreateTimeFrom;
getOrders.CreateTimeTo = CreateTimeTo;

getOrders.Execute();

if (getOrders.ApiResponse.Ack != AckCodeType.Failure)
{
//Check if any orders are returned
if (getOrders.ApiResponse.OrderArray.Count != 0)
{
foreach (OrderType order in getOrders.ApiResponse.OrderArray)
{
//Update your system with the order information.
Console.WriteLine(“Order Number: ” + order.OrderID);
Console.WriteLine(“OrderStatus: ” + order.OrderStatus);
Console.WriteLine(“Order Created On: ” + order.CreatedTime);

//Get Order Details
TransactionTypeCollection orderTrans = order.TransactionArray;

//Order could be comprised of one or more items
foreach (TransactionType transaction in orderTrans)
{
Console.WriteLine(“Order for: ” + transaction.Item.ItemID + “, ” + transaction.Item.SKU + “, ” + transaction.Item.Title);

//If you are listing variation items, you will need to retrieve the variation
//details as chosen by the buyer
if (transaction.Variation.SKU != null)
{
Console.WriteLine(“Variation: ” + transaction.Variation.SKU);
}
Console.WriteLine(“OrderLineItemID: ” + transaction.OrderLineItemID);
Console.WriteLine(“Qty Purchased: ” + transaction.QuantityPurchased);
Console.WriteLine(“Buyer Info: ” + order.BuyerUserID + “, ” + transaction.Buyer.Email);

}

if (order.CheckoutStatus.Status == CompleteStatusCodeType.Complete)
{
//Get Payment Details
Console.WriteLine(“Order Adjustment Amount: ” + order.AdjustmentAmount.Value);
Console.WriteLine(“Order Amount Paid: ” + order.AmountPaid.Value);
Console.WriteLine(“Payment Method: ” + order.CheckoutStatus.PaymentMethod);

ExternalTransactionTypeCollection extTrans = order.ExternalTransaction;

foreach(ExternalTransactionType extTran in extTrans)
{
Console.WriteLine(“External TransactionID: ” + extTran.ExternalTransactionID);
Console.WriteLine(“External Transaction Time: ” + extTran.ExternalTransactionTime);
Console.WriteLine(“Payment/Refund Amount: ” + extTran.PaymentOrRefundAmount.Value);
}

//Get shipping information
ShippingServiceOptionsType shipping;
shipping = order.ShippingServiceSelected;

Console.WriteLine(“Shipping Service Selected: ” + order.ShippingServiceSelected.ShippingService);

//Get Shipping Address – Address subject to change if the buyer has not completed checkout
AddressType address = order.ShippingAddress;

StringBuilder sAdd = new StringBuilder();
sAdd = sAdd.Append(address.Name);
if (address.Street != null && address.Street != “”)
sAdd.Append(“, ” + address.Street);
if (address.Street1 != null && address.Street1 != “”)
sAdd.Append(“, ” + address.Street1);
if (address.Street2 != null && address.Street2 != “”)
sAdd.Append(“, ” + address.Street2);
if (address.CityName != null && address.CityName != “”)
sAdd.Append(“, ” + address.CityName);
if (address.StateOrProvince != null && address.StateOrProvince != “”)
sAdd.Append(“, ” + address.StateOrProvince);
if (address.PostalCode != null && address.PostalCode != “”)
sAdd.Append(“, ” + address.PostalCode);
if (address.CountryName != null && address.CountryName != “”)
sAdd.Append(“, ” + address.CountryName);
if (address.Phone != null && address.Phone != “”)
sAdd.Append(“: Phone” + address.Phone);

Console.WriteLine(“Shipping Address: ” + sAdd);

double salesTax;
//Get the sales tax
if (order.ShippingDetails.SalesTax.SalesTaxAmount == null)
salesTax = 0.00;
else
salesTax = order.ShippingDetails.SalesTax.SalesTaxAmount.Value;

Console.WriteLine(“Sales Tax: ” + salesTax);

if (order.BuyerCheckoutMessage != null)
{
Console.WriteLine(“Buyer Checkout Message: ” + order.BuyerCheckoutMessage);
}

}
Console.WriteLine(“********************************************************”);
}
}
}

}
}
}

.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”);

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