Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获得';错误:找不到参数';使用Magento SOAP API v1和Savon Ruby Gem v2创建类别时 背景_Ruby_Api_Magento_Soap_Savon - Fatal编程技术网

获得';错误:找不到参数';使用Magento SOAP API v1和Savon Ruby Gem v2创建类别时 背景

获得';错误:找不到参数';使用Magento SOAP API v1和Savon Ruby Gem v2创建类别时 背景,ruby,api,magento,soap,savon,Ruby,Api,Magento,Soap,Savon,我正试图通过MagentoSOAPAPI使用创建一个类别。在有人建议之前,我不能使用MagentoSOAPV2或RESTAPI 此代码设置我的客户端并登录: @client = Savon.client(wsdl: "#{EnvConfig.base_url}/api/soap/?wsdl", log_level: :debug, raise_errors: true, pretty_print_xml: true) response = @client.call(:login, messag

我正试图通过MagentoSOAPAPI使用创建一个类别。在有人建议之前,我不能使用MagentoSOAPV2或RESTAPI

此代码设置我的客户端并登录:

@client = Savon.client(wsdl: "#{EnvConfig.base_url}/api/soap/?wsdl", log_level: :debug, raise_errors: true, pretty_print_xml: true)

response = @client.call(:login, message: {
  username: EnvConfig.magento_api_user,
  apiKey: EnvConfig.magento_api_key
})

@token = response.to_hash[:login_response][:login_return]
然后我可以调用magentos的各种方法。到,我可以打电话:

@response = @client.call(:call, message: {session: @token, method: 'catalog_product.list'})
这一切都正常工作,所以上面的任何代码似乎都没有问题

问题 当我打电话时,我发现一个错误。如果我仅使用parentID参数调用该方法:

  @response = @client.call(:call, message: {session: @token, method: 'catalog_category.create', parent_id: 90})
然后由Savon发送以下XML:

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:typens="urn:Magento" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <typens:call>
      <session>6939ace91ba26b1da9a21334d7ef2c13</session>
      <method>catalog_category.create</method>
      <parentId>90</parentId>
    </typens:call>
  </env:Body>
</env:Envelope>
我希望如此,因为它清楚地表明以下属性不是可选的:

  • 父ID
  • 类群
    • 名字
    • 你是活跃的吗
    • 可用\u排序\u
    • 默认排序依据
    • 在菜单中包含
因此,如果我打一个包含
名称
的电话:

@response = @client.call(:call, message: {session: @token, method: 'catalog_category.create', parent_id: 90, category_data: {name: 'Fooooo'}})
此XML将发送到:

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:typens="urn:Magento" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <typens:call>
      <session>6939ace91ba26b1da9a21334d7ef2c13</session>
      <method>catalog_category.create</method>
      <parentId>90</parentId>
      <categoryData>
        <name>Fooooo</name>
      </categoryData>
    </typens:call>
  </env:Body>
</env:Envelope>
我花了相当长的时间试图解决这个问题,并尝试发送
name
参数,而不将其包装在categoryData以及其他参数中。它们都返回相同的错误消息

至少,最好知道找不到哪个参数


任何帮助都将不胜感激:)

我真的找不到一个像样的解决方案。最后,通过使用以下极其混乱的代码构建XML,解决了这个问题:

# Builds an XML Request for use with the Magento API
#-------------------------------------------------------------------------------------------------------------
# Usage:
#
# @m = MageAPI.new(token, call, params)   Creates a new MageAPIRequest object with @call, @token, @data and
#                                           @xml_data instance variables.
#
# Expects a hash of params like:
#
#      { parentId: '90',
#        categoryData: {
#          name: 'OMG, does this work?',
#          is_active: 1,
#          available_sort_by: 'position',
#          default_sort_by: 'position',
#          description: 'Foo',
#          url_key: 'url_key',
#          include_in_menu: 1}
#      }
#
#-------------------------------------------------------------------------------------------------------------
class MageAPIRequest
  attr_reader :call, :token, :data, :xml_data
  def initialize(token, call, params = {})
    @call = call
    @token = token
    @data = params
    @xml_data = build_xml
  end

  def to_s
    return @xml_data
  end

  # Build out the xml string to send to the server, excluding the Envelope, body and call tags, which are added by Savon.
  def build_xml
    token = LibXML::XML::Node.new('sessionId', @token)
    token['xsi:type']='xsd:string'
    resourcePath = LibXML::XML::Node.new('resourcePath', @call)
    resourcePath['xsi:type']='xsd:string'

    unless @data.empty?
      args = LibXML::XML::Node.new 'args'
      args['SOAP-ENC:arrayType'] = "xsd:ur-type[#{@data.length}]"
      args['xsi:type'] = 'SOAP-ENC:Array'

      # Build the structure insude 'args', based on the Hash.
      # TODO: Make this recursive, so it can work deeper than one level.
      @data.each do |k,v|
        if v.is_a? Hash

          details = LibXML::XML::Node.new(k.to_s)
          details["xsi:type"] = 'ns2:Map'
          args << details

          v.each do |key,value|

            item_node = LibXML::XML::Node.new("item")

            key_node = LibXML::XML::Node.new("key", key.to_s)
            key_node['xsi:type'] = 'xsd:string'

            if value.is_a? Fixnum
              value_node = LibXML::XML::Node.new("value", value.to_s)
              value_node['xsi:type'] = 'xsd:int'
            elsif value.is_a? Float
              value_node = LibXML::XML::Node.new("value", sprintf("%.2f", value))
              value_node['xsi:type'] = 'xsd:string'
            elsif value.is_a? Array
              value_node = LibXML::XML::Node.new("value")
              value_node['SOAP-ENC:arrayType'] = "xsd:int[#{value.length}]"
              value_node['xsi:type'] = 'SOAP-ENC:Array'

              value.each do |v|
                v_node = LibXML::XML::Node.new("item", v.to_s)
                v_node['xsi:type'] = 'xsd:string'
                v_node['xsi:type'] = 'xsd:int' if v.is_a? Fixnum
                value_node << v_node
              end

            else
              value_node = LibXML::XML::Node.new("value", value.to_s)
              value_node['xsi:type'] = 'xsd:string'
            end

            item_node << key_node
            item_node << value_node
            details << item_node

          end

        else
          pair = LibXML::XML::Node.new(k.to_s, v.to_s)
          # if v.is_a? Fixnum
          #    pair['xsi:type']='xsd:int'
          # else
            pair['xsi:type']='xsd:string'
          # end
          args << pair
        end
      end
    end
    xml_string = token.to_s
    xml_string << resourcePath.to_s
    xml_string << args.to_s
  end


end
虽然远非理想,但它确实有效。值得注意的是,我还必须构建一个解析器来转换如下所示的响应:

  {:balance=>"10",
    :exchange_rate=>"1.000000",
    :response_type=>"ACCEPT",
    :customer_data=>
      {:item=>
        [
          {:key=>"iredeem_member_id", :value=>"110"},
          {:key=>"prefix", :value=>"Ms."},
          {:key=>"lastname", :value=>"Last name"},
          {:key=>"firstname", :value=>"First name"},
          {:key=>"iredeem_points_balance", :value=>"10"},
        ]
      }
  }
  {:balance=>"10",
    :exchange_rate=>"1.000000",
    :response_type=>"ACCEPT",
    :customer_data=>
      {:iredeem_member_id=>"110",
       :prefix=>"Ms.",
       :lastname=>"Last name",
       :firstname=>"First name",
       :iredeem_points_balance=>"10"
      }
  }
变成这样有用的东西:

  {:balance=>"10",
    :exchange_rate=>"1.000000",
    :response_type=>"ACCEPT",
    :customer_data=>
      {:item=>
        [
          {:key=>"iredeem_member_id", :value=>"110"},
          {:key=>"prefix", :value=>"Ms."},
          {:key=>"lastname", :value=>"Last name"},
          {:key=>"firstname", :value=>"First name"},
          {:key=>"iredeem_points_balance", :value=>"10"},
        ]
      }
  }
  {:balance=>"10",
    :exchange_rate=>"1.000000",
    :response_type=>"ACCEPT",
    :customer_data=>
      {:iredeem_member_id=>"110",
       :prefix=>"Ms.",
       :lastname=>"Last name",
       :firstname=>"First name",
       :iredeem_points_balance=>"10"
      }
  }

你还在做这个吗?您是否尝试使用SoapUI创建正确的SOAP请求?通过自己构建XML,成功地“解决”了这个问题。我刚刚发布了一个答案。在我看来,你可以将Savon与builder一起使用,并让它解析结果。但如果它能工作,就不要碰它:-)。我似乎记得尝试使用builder时发现(令人惊讶的是)使用LibXML没有那么痛苦。
  {:balance=>"10",
    :exchange_rate=>"1.000000",
    :response_type=>"ACCEPT",
    :customer_data=>
      {:iredeem_member_id=>"110",
       :prefix=>"Ms.",
       :lastname=>"Last name",
       :firstname=>"First name",
       :iredeem_points_balance=>"10"
      }
  }