Search code examples
c#.netweb-servicessoap-clientsabre

Sabre Web Services - Property Description Service Auth Error - ERR.SWS.CLIENT.VALIDATION_FAILED


I'm trying to make a call to the HotelPropertyDescriptionLLSRQ Sabre Web Service using C#. I've gotten other APIs to work with similar code but I keep getting the same Client Validation Failed error, even after retrieving a valid security token.

I think I'm missing some small piece in the proxy model, which is below.

Search Criteria Object:

HotelSearchCriteria searchCriteria = new HotelSearchCriteria
            {
                hotelCode = "1191",
                inDate = "8-22",
                outDate = "8-25"
            };

And then the proxy class:

public class HotelPropertyDescriptionReq
{
    private HotelPropertyDescriptionService service;
    private HotelPropertyDescriptionRQ req;
    public HotelPropertyDescriptionRS response;
    public string xmlResponse;
    public bool searchPerformed = false;

    public HotelPropertyDescriptionReq()
    {
        //parameterless constructor for serialization
    }

    public HotelPropertyDescriptionReq(SessionToken token, HotelSearchCriteria searchCriteria)
    {
        //argument validation - must have a location of some sort and some dates for search to work. Throw exception here if none found
        if (searchCriteria.hotelCode == null && searchCriteria.cityCode == null)
        {
            //no search can take place if this is null...send back an empty response with searchPerformed == fals
            throw new ArgumentException("Cannot search hotel availability without hotelCode or cityCode");

        }
        else if (searchCriteria.inDate == null || searchCriteria.outDate == null)
        {
            throw new ArgumentException("Cannot serach hotel availability without inDate and outDate");
        }
        //MessageHeader
        MessageHeader mHeader = new MessageHeader();

        PartyId[] pId = { new PartyId() };
        pId[0].Value = "SWS";

        From from = new From();
        from.PartyId = pId;

        To to = new To();
        to.PartyId = pId;

        mHeader.Action = "HotelPropertyDescriptionLLSRQ";
        mHeader.version = "2.3.0";
        mHeader.Service = new Service()
        {
            Value = mHeader.Action
        };
        mHeader.ConversationId = token.conversationID;
        mHeader.CPAId = token.ipcc;
        mHeader.From = from;
        mHeader.To = to;

        mHeader.MessageData = new MessageData()
        {
            Timestamp = DateTime.UtcNow.ToString(),
        };


        //Security
        //Security sec = new Security();
        Security1 sec = new Security1();
        sec.BinarySecurityToken = token.securityToken;


        //Service
        service = new HotelPropertyDescriptionService();
        service.MessageHeaderValue = mHeader;
        //service.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap11;
        service.Security = sec;

        //request
        req = new HotelPropertyDescriptionRQ();

        req.AvailRequestSegment = new HotelPropertyDescriptionRQAvailRequestSegment();
        req.AvailRequestSegment.GuestCounts = new HotelPropertyDescriptionRQAvailRequestSegmentGuestCounts();
        req.AvailRequestSegment.GuestCounts.Count = "1";

        req.AvailRequestSegment.HotelSearchCriteria = new HotelPropertyDescriptionRQAvailRequestSegmentHotelSearchCriteria();
        req.AvailRequestSegment.HotelSearchCriteria.Criterion = new HotelPropertyDescriptionRQAvailRequestSegmentHotelSearchCriteriaCriterion();
        req.AvailRequestSegment.HotelSearchCriteria.Criterion.HotelRef = new HotelPropertyDescriptionRQAvailRequestSegmentHotelSearchCriteriaCriterionHotelRef();

        req.AvailRequestSegment.HotelSearchCriteria.Criterion.HotelRef.HotelCode = searchCriteria.hotelCode;

        req.AvailRequestSegment.TimeSpan = new HotelPropertyDescriptionRQAvailRequestSegmentTimeSpan();
        req.AvailRequestSegment.TimeSpan.Start = searchCriteria.inDate;
        req.AvailRequestSegment.TimeSpan.End = searchCriteria.outDate;

        string requestXML = Serializer.toXML(req);
        string headerXML = Serializer.toXML(mHeader);


        //send the request
        try

        {
            response = service.HotelPropertyDescriptionRQ(req);
            searchPerformed = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }
    }
}

Solution

  • Here is a working request - your payload looks a little bit diffrent then the one created by you. Just try to replicate this - need to set the PCC and securitycredentials:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
        <SOAP-ENV:Header>
            <eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:version="2.0">
                <eb:From>
                    <eb:PartyId type="urn:x12.org:IO5:01">1212</eb:PartyId>
                </eb:From>
                <eb:To>
                    <eb:PartyId type="urn:x12.org:IO5:01">2323</eb:PartyId>
                </eb:To>
                <eb:CPAId>YOURPCCHERE</eb:CPAId>
                <eb:ConversationId>XXX-dd74-4500-99d6-1e746b8876cc1507217090989</eb:ConversationId>
                <eb:Service eb:type="OTA">HotelPropertyDescriptionLLSRQ</eb:Service>
                <eb:Action>HotelPropertyDescriptionLLSRQ</eb:Action>
                <eb:MessageData>
                    <eb:MessageId>1001</eb:MessageId>
                    <eb:Timestamp>2016-06-07T10:00:01</eb:Timestamp>
                    <eb:TimeToLive>2017-06-06T23:59:59</eb:TimeToLive>
                </eb:MessageData>
            </eb:MessageHeader>
            <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/12/utility">
                <wsse:BinarySecurityToken EncodingType="wsse:Base64Binary" valueType="String">YOURSECRETHERE</wsse:BinarySecurityToken>
            </wsse:Security>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
            <HotelPropertyDescriptionRQ xmlns="http://webservices.sabre.com/sabreXML/2011/10" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ReturnHostCommand="false" TimeStamp="2015-11-30T12:00:00-06:10" Version="2.3.0">
                <AvailRequestSegment>
                 <GuestCounts Count="1"/>
                    <HotelSearchCriteria>
                        <Criterion>
                            <HotelRef HotelCode="0022426" UnitOfMeasure="KM"/>
                        </Criterion>
                    </HotelSearchCriteria>
                    <POS>
                        <Source>
                            <CompanyName Division="BER"/>
                        </Source>
                    </POS>
                    <TimeSpan End="04-24" Start="04-22" />
                </AvailRequestSegment>
            </HotelPropertyDescriptionRQ>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>