2

I am building a website to search for flights data using Insta Flight Search API by Sabre. After thoroughly reading the docs provided by them and testing the API in the API Explorer where everything worked perfectly giving me the exact idea how the API will work.

To start with i just created a simple form with 2 select boxes which are providing the source and destination IATA codes, and 2 date input boxes giving the departure and return date. I have been searching for solutions for more than a week and tried various solutions i found, but every time i get either a 400 BAD REQUEST or 401 UNAUTHORIZED response.

I also checked the Demo Gallery but at the time of writing there was no sample for C#, even on Stack-Overflow there are only 78 questions tagged sabre and just 1 tagged sabre and C#

I contacted the support but received a response.

Please bear in mind that we do not provide code support. Could you please share the XML (Sabre) files?

I know i am missing something really silly, but after trying everything i can think of, i am resorting to the community for help. I am attaching both the code files.

Note: Commented code represents the various methods i have tried

Controller Code :

using System;
using System.Net;
using System.Net.Http;
using System.Web.Mvc;
using System.Threading.Tasks;

namespace Sabre_sample_1.Controllers
{
    public class HomeController : Controller
    {
        public async Task<ActionResult> Index()
        {
            if (Request.HttpMethod == "POST")
            {
            string Origin = Request.Form["Origin"];
            string Destination = Request.Form["Destination"];
            DateTime Departure = Convert.ToDateTime(Request.Form["Departure"]);
            string departuredatestr = Departure.Year.ToString() + "-" + Departure.Month.ToString() + "-" + Departure.Day.ToString();
            DateTime Return = Convert.ToDateTime(Request.Form["Return"]);
            string returndatestr = Return.Year.ToString() + "-" + Return.Month.ToString() + "-" + Return.Day.ToString();

            WebClient datawebclient = new WebClient();
            string url = "https://" + "api.test.sabre.com/v1/shop/flights?origin=" + Origin + "&destination=" + Destination
                + "&departuredate=" + departuredatestr + "&returndate=" + returndatestr + "&onlineitinerariesonly=N"
                + "&limit=10&offset=1&eticketsonly=N&sortby=totalfare&order=asc&sortby2=departuretime&order2=asc"
                + "&pointofsalecountry=US";
            string data = string.Empty;
            string AccessToken = "*Access Token*";
            //datawebclient.Headers.Add("Authorization", "Bearer " + AccessToken);
            //datawebclient.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + AccessToken);
            //datawebclient.Headers.Add(HttpRequestHeader.Authorization, AccessToken);
            //data = datawebclient.DownloadString(url);

            //HttpClient httpClient = new HttpClient();
            //httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken);
            //data = await httpClient.GetStringAsync(url);

            using (var client = new HttpClient())
            {
                //url = "https://www.theidentityhub.com/{tenant}/api/identity/v1";
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + AccessToken);
                data = await client.GetStringAsync(url);
                // Parse JSON response.

            }

            ViewBag.url = url;
            ViewBag.data = data;
            //RedirectResult redirectresult = new RedirectResult(url);
        }
        return View();
    }
}
}

Index.cshtml :

<form class="form-horizontal" method="post">
<fieldset>
    <legend>Enter Details</legend>
    <div class="form-group">
        <label for="select" class="col-lg-2 control-label">Origin</label>
        <div class="col-lg-10">
            <select class="form-control" name="Origin" required>
                <option></option>
                <option value="JFK">John F. Kennedy International Airport</option>
                <option value="EZE">Ministro Pistarini</option>
                <option value="MIA">Miami International Airport</option>
            </select>
        </div>
    </div>
    <div class="form-group">
        <label for="select" class="col-lg-2 control-label">Destination</label>
        <div class="col-lg-10">
            <select class="form-control" name="Destination" required>
                <option></option>
                <option value="JFK">John F. Kennedy International Airport</option>
                <option value="EZE">Ministro Pistarini</option>
                <option value="MIA">Miami International Airport</option>
            </select>
        </div>
    </div>
    <div class="form-group">
        <label for="inputEmail" class="col-lg-2 control-label">Departure</label>
        <div class="col-lg-10">
            <input type="date" class="form-control" name="Departure"required>
        </div>
    </div>
    <div class="form-group">
        <label for="inputEmail" class="col-lg-2 control-label">Return</label>
        <div class="col-lg-10">
            <input type="date" class="form-control" name="Return" required>
        </div>
    </div>
    <div class="form-group">
        <div class="col-lg-10 col-lg-offset-2">
            <input name="endpointName" type="hidden" value="Air Search" class="form-control">
            <input name="methodName" type="hidden" value="InstaFlights Search" class="form-control">
            <input name="httpMethod" type="hidden" value="GET" class="form-control">
            <input name="methodUri" type="hidden" value="/v1/shop/flights" class="form-control">
            <button type="reset" class="btn btn-default">Cancel</button>
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
</fieldset>
</form>
<h2>Url</h2>
@ViewBag.url
<hr />
<h2>Data</h2>
@ViewBag.data

Other Stack Overflow Questions which are closest to my problem, but didn't solved my problem.

FINAL EDIT

After weeks of struggling with the possible solution, i found the answer in the formatting of the response. A JSON object contains the objects as strings in " enclosing, but the whole response is also a string which makes the internal " enclosing to \"

But last month have made me realize the need for a proper tutorial for Sabre for developers in ASP.NET MVC C#, so i will publishing a blog post and a Nuget Package for other peers. I'll share the links once they are live.

Community
  • 1
  • 1
Abhishek Siddhu
  • 577
  • 6
  • 22

3 Answers3

0

The following code is working fine for me.

FlightObject f = new FlightObject();
string URL = "https://api.test.sabre.com/v2/shop/flights?origin=JFK&destination=LAX&departuredate=2016-02-04&returndate=2016-02-20&pointofsalecountry=US&passengercount=2";
using (var w = new WebClient())
{
    w.Headers.Add(HttpRequestHeader.Authorization, token_type + " " + access_token);
    string str = w.DownloadString(URL);
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(FlightObject));
    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(str)))
    {
        f = (FlightObject)serializer.ReadObject(ms);
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Khaan
  • 759
  • 7
  • 23
  • for test environment Sabre do not work for many sectors use these iatacodes, its working for me.. also use api explorer https://developer.sabre.com/io-docs for successful request response... – Khaan Jan 18 '16 at 11:40
  • Which namespace contains the Type FlightObject – Abhishek Siddhu Jan 18 '16 at 12:00
  • 1
    Just copy the response from InstaFlights Search https://developer.sabre.com/io-docs and then generate Classes objects for serialization using http://json2csharp.com/ link.. – Khaan Jan 18 '16 at 12:30
  • the question is not about parsing the data, its about authenticating the request. I am not able to even reach the serialization steps – Abhishek Siddhu Jan 18 '16 at 20:32
  • Though this answer didn't solved the original question, i learned a new thing i.e. json2csharp so a +1 – Abhishek Siddhu Feb 01 '16 at 02:56
0

Assuming you're getting the Access Token first, using the /v2/auth/token REST service, right?

https://developer.sabre.com/docs/read/rest_basics/authentication

Also, can you try this approach?

// Add this on top
using System.Net.Http.Headers;
// then......
//....... 

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
        data = await client.GetStringAsync(url);

    }
Ajay2707
  • 5,690
  • 6
  • 40
  • 58
fcarreno
  • 701
  • 4
  • 8
  • ooops. Sorry I just noted you tried that in your commented code. Assuming you have obtained a correct access token using the /v2/auth/token service, then I can't see what's wrong with your code. Have you tried with another REST client tool (e.g.: soapUI, Postman), to make sure you're setting all params correctly? – fcarreno Jan 18 '16 at 18:06
  • yes i am able to authenticate and receive an access token from the server perfectly fine without any issues. – Abhishek Siddhu Jan 18 '16 at 20:29
  • 2
    In that case I'd try with a tool monitoring the traffic (http request uri and headers) generated from your app, and compare with the correct format (vs. Sabre API Explorer or another tool - e.g.: soapUI - that you know it's working) – fcarreno Jan 20 '16 at 13:32
  • thanks, monitoring of traffic led me in the right direction, i have posted the answer. +1 for the help. – Abhishek Siddhu Feb 01 '16 at 02:58
0

After weeks of struggling with the possible solution, i found the answer in the formatting of the response. A JSON object contains the objects as strings in " enclosing, but the whole response is also a string which makes the internal " enclosing to \"

But last month have made me realize the need for a proper tutorial for Sabre for developers in ASP.NET MVC C#, so i will publishing a blog post and a Nuget Package for other peers. I'll share the links once they are live.

Happy Coding.

Abhishek Siddhu
  • 577
  • 6
  • 22