【问题标题】:Amadeus Airport Autocomplete using API on C#在 C# 上使用 API 的 Amadeus Airport Autocomplete
【发布时间】:2016-10-07 13:38:39
【问题描述】:

我在 C# 上开发一个应用程序,并且我正在使用 Amadeus 的 C# 库。 我试图获得如下所示的 AirportAutocomplete 响应:

[ { "value": "MAD", "label": "Adolfo Suárez Madrid–Barajas Airport [MAD]" } ]

由于响应包含在括号中,它不仅是一个 AiportAutocompleteResponse 类,它更像是一个数组或 AirportAutocompleteResponse 类的列表。如果有更多与搜索匹配的地方,我将收到类似this example 的回复。

AirportAutocompleteResponse 类:

public partial class AirportAutocompleteResponse :  IEquatable<AirportAutocompleteResponse>
{
    /// <summary>
    /// Initializes a new instance of the <see cref="AirportAutocompleteResponse" /> class.
    /// </summary>
    public AirportAutocompleteResponse()
    {

    }


    /// <summary>
    /// The 3 letter IATA location code of the given city or airport. You can use this as an input parameter for a flight low-fare or inspiration search.
    /// </summary>
    /// <value>The 3 letter IATA location code of the given city or airport. You can use this as an input parameter for a flight low-fare or inspiration search.</value>
    [DataMember(Name="value", EmitDefaultValue=false)]
    public string Value { get; set; }


    /// <summary>
    /// The name of this airport, in UTF-8 format, prefixed with the name of the city if it is not already incorporated in the name of the airport, and appended with the location's IATA code (as in value), enclosed in square brackets.
    /// </summary>
    /// <value>The name of this airport, in UTF-8 format, prefixed with the name of the city if it is not already incorporated in the name of the airport, and appended with the location's IATA code (as in value), enclosed in square brackets.</value>
    [DataMember(Name="label", EmitDefaultValue=false)]
    public string Label { get; set; }



    /// <summary>
    /// Returns the string presentation of the object
    /// </summary>
    /// <returns>String presentation of the object</returns>
    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.Append("class AirportAutocompleteResponse {\n");
        sb.Append("  Value: ").Append(Value).Append("\n");
        sb.Append("  Label: ").Append(Label).Append("\n");

        sb.Append("}\n");
        return sb.ToString();
    }

    /// <summary>
    /// Returns the JSON string presentation of the object
    /// </summary>
    /// <returns>JSON string presentation of the object</returns>
    public string ToJson()
    {
        return JsonConvert.SerializeObject(this, Formatting.Indented);
    }

    /// <summary>
    /// Returns true if objects are equal
    /// </summary>
    /// <param name="obj">Object to be compared</param>
    /// <returns>Boolean</returns>
    public override bool Equals(object obj)
    {
        // credit: http://stackoverflow.com/a/10454552/677735
        return this.Equals(obj as AirportAutocompleteResponse);
    }

    /// <summary>
    /// Returns true if AirportAutocompleteResponse instances are equal
    /// </summary>
    /// <param name="other">Instance of AirportAutocompleteResponse to be compared</param>
    /// <returns>Boolean</returns>
    public bool Equals(AirportAutocompleteResponse other)
    {
        // credit: http://stackoverflow.com/a/10454552/677735
        if (other == null)
            return false;

        return 
            (
                this.Value == other.Value ||
                this.Value != null &&
                this.Value.Equals(other.Value)
            ) && 
            (
                this.Label == other.Label ||
                this.Label != null &&
                this.Label.Equals(other.Label)
            );
    }

    /// <summary>
    /// Gets the hash code
    /// </summary>
    /// <returns>Hash code</returns>
    public override int GetHashCode()
    {
        // credit: http://stackoverflow.com/a/263416/677735
        unchecked // Overflow is fine, just wrap
        {
            int hash = 41;
            // Suitable nullity checks etc, of course :)

            if (this.Value != null)
                hash = hash * 59 + this.Value.GetHashCode();

            if (this.Label != null)
                hash = hash * 59 + this.Label.GetHashCode();

            return hash;
        }
    }

}

以及我用来调用 API 的函数:

public AirportAutocompleteResponse AirportAutocomplete (string apikey, string term)
    {
         ApiResponse<AirportAutocompleteResponse> response = AirportAutocompleteWithHttpInfo(apikey, term);
         return response.Data;
    }

    /// <summary>
    /// The Airport Autocomplete API provides a simple means to find an IATA location code for flight search based on a city or airport name. The API is fully JQuery-Autocomplete compatible to enable you to quickly build a drop-down list for your users to find the right airport easily. Given the start of any word in an airport&#39;s official name, a city name, or the start of an IATA code, this API provides the full name and IATA location code of the city or airport, for use in flight searches. Only major cities and civilian airports with several commercial flights per week are included by default. The response provides up to 20 possible matches, sorted by importance, in a &lt;a href=\&quot;http://jqueryui.com/autocomplete/\&quot;&gt;JQuery UI Autocomplete&lt;/a&gt; compatible format. &lt;a href=\&quot;https://github.com/amadeus-travel-innovation-sandbox/sandbox-content/blob/master/airport-autocomplete-template.html\&quot;&gt;This sample implementation&lt;/a&gt; using JQuery UI may help. This API uses data from the OpenTravelData project, see https://github.com/opentraveldata/opentraveldata/blob/master/opentraveldata/optd_por_public.csv.\n\nThe value returned is the IATA location code. The label returned is always in UTF-8 format, with the airport official name (which is often in the native language), in the format of English City Name (if not already included in the airport name).
    /// </summary>
    /// <param name="apikey">API Key provided for your account, to identify you for API access</param> 
    /// <param name="term">Search term that should represent some part of a city or airport name.</param> 
    /// <returns>ApiResponse of AirportAutocompleteResponse</returns>
    public ApiResponse< AirportAutocompleteResponse > AirportAutocompleteWithHttpInfo (string apikey, string term)
    {

        // verify the required parameter 'apikey' is set
        if (apikey == null)
            throw new ApiException(400, "Missing required parameter 'apikey' when calling DefaultApi->AirportAutocomplete");

        // verify the required parameter 'term' is set
        if (term == null)
            throw new ApiException(400, "Missing required parameter 'term' when calling DefaultApi->AirportAutocomplete");


        var path_ = "/airports/autocomplete";

        var pathParams = new Dictionary<String, String>();
        var queryParams = new Dictionary<String, String>();
        var headerParams = new Dictionary<String, String>(Configuration.DefaultHeader);
        var formParams = new Dictionary<String, String>();
        var fileParams = new Dictionary<String, FileParameter>();
        Object postBody = null;

        // to determine the Content-Type header
        String[] httpContentTypes = new String[] {

        };
        String httpContentType = Configuration.ApiClient.SelectHeaderContentType(httpContentTypes);

        // to determine the Accept header
        String[] httpHeaderAccepts = new String[] {
            "application/json"
        };
        String httpHeaderAccept = Configuration.ApiClient.SelectHeaderAccept(httpHeaderAccepts);
        if (httpHeaderAccept != null)
            headerParams.Add("Accept", httpHeaderAccept);

        // set "format" to json by default
        // e.g. /pet/{petId}.{format} becomes /pet/{petId}.json
        pathParams.Add("format", "json");

        if (apikey != null) queryParams.Add("apikey", Configuration.ApiClient.ParameterToString(apikey)); // query parameter
        if (term != null) queryParams.Add("term", Configuration.ApiClient.ParameterToString(term)); // query parameter







        // make the HTTP request
        IRestResponse response = (IRestResponse) Configuration.ApiClient.CallApi(path_, 
            Method.GET, queryParams, postBody, headerParams, formParams, fileParams,
            pathParams, httpContentType);

        int statusCode = (int) response.StatusCode;

        if (statusCode >= 400)
            throw new ApiException (statusCode, "Error calling AirportAutocomplete: " + response.Content, response.Content);
        else if (statusCode == 0)
            throw new ApiException (statusCode, "Error calling AirportAutocomplete: " + response.ErrorMessage, response.ErrorMessage);

        return new ApiResponse<AirportAutocompleteResponse>(statusCode,
            response.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),
            (AirportAutocompleteResponse) Configuration.ApiClient.Deserialize(response, typeof(AirportAutocompleteResponse)));

    }

我想做的是从响应中检索信息,以便以后可以使用它,这是我到目前为止所尝试的:

        string apiKey = "MyApiKey";  //Not shown for obvious reasons
        DefaultApi Amadeus = new DefaultApi("https://api.sandbox.amadeus.com/v1.2");    


        AirportAutocompleteResponse response = Amadeus.AirportAutocomplete(apiKey, "adolfo suarez");                   
        textBox3.Text = response.ToString(); 




        /**********************TRIED*************************/

        /*****USING A LIST*****/
        /*
        List<AirportAutocompleteResponse> response = Amadeus.AirportAutocomplete(apiKey, "adolfo suarez");    
        textBox3.Text = response.ToString();
        */ //Does not compile since the response its not a list



        /*****AS ARRAY*****/
        //AirportAutocompleteResponse[] response = Amadeus.AirportAutocomplete(apiKey, "adolfo suarez");   
        //textBox3.Text = response.ToString(); //Doesnt work neither



        /*****AS STRING*****/

        /*
        string response = Amadeus.AirportAutocomplete(apiKey, "adolfo suarez").ToString();    
        textBox3.Text = response.ToString();
        */ //DOESNT WORK

我得到它的例外:

在 IO.Swagger.dll 中发生了“IO.Swagger.Client.ApiException”类型的未处理异常 附加信息:无法将当前 JSON 数组(例如 [1、2、3])反序列化为类型“IO.Swagger.Model.AirportAutocompleteResponse”,因为该类型需要 JSON 对象(例如 {“name”:“value”}) 正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),例如 List 可以从 JSON 数组反序列化。也可以将 JsonArrayAttribute 添加到类型中以强制它从 JSON 数组中反序列化。

由于 AirportAutocomplete 它是一个类,并且响应似乎是 AirportAutocomplete 类的列表或数组,我得到了之前提到的异常,我尝试使用列表来获取上面显示的响应和数组,但没有任何效果。我似乎有些人以前遇到过这个问题,他们通过

解决了这个问题
Deserialize<AiportAutocomplete>

作为

Deserialize<List<AiportAutocomplete>>

但由于我使用了 API 类,我无法更改它。 ¿ 有没有办法无需我自己的反序列化器就可以解决这个问题?

很抱歉扩展名,但我想包含所有可能提供帮助的信息。

【问题讨论】:

  • 听起来 API 类已经过时了,如果它不能与开箱即用的真正 API 一起使用的话。我建议您向 Amadeus 提交错误。

标签: c# amadeus


【解决方案1】:

感谢 Obito 强调这个问题,我能够重现它。正如上面 Rup 所说,这确实是the Swagger Specification that is used to build our client library 中的一个错误。

我已修复该错误并验证它现在对我有效。 如果它仍然不适合您,请告诉我们,否则请随时将此答案标记为正确;)

【讨论】:

    猜你喜欢
    • 2016-09-13
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    相关资源
    最近更新 更多