views:

215

answers:

2

I'm trying to get the sample FedEx Address Verification application to work in C#. After contacting my FedEx technical contact and having him activate Address Verification on my test account (apparently it is considered an advanced service that requires additional permissions) I was able to compile and run the example application.

However, I wasn't getting quite the results I expected given the settings...

request.Options.ConvertToUpperCase = true;
request.Options.CheckResidentialStatus = true;

Based on these flags, I expected to have the address come back in upper case, and to be able to check the Residential or ResidentialStatus properties to determine commercial vs residential. Neither were occuring.

So I installed Fiddler to see the exact SOAP exchange that was taking place and found that the outbound Options tag was not populating except for one property, MaximumNumberOfMatches.

Is there something I should check for in the Reference.cs file that is created by Visual Studio? I didn't see anything out of the norm, but something is happening that is preventing the serialization of some of the properties.

--Edit--

Updated my code as per the suggestion below. Unfortunately, it still only populates 2 of the options parameters. I've included the C# settings code and the outbound/inbound SOAP request below. Can anyone think of a reason the rest of the options are not being sent in the SOAP request?

AddressValidationRequest request = new AddressValidationRequest();
            //
            request.WebAuthenticationDetail = new WebAuthenticationDetail();
            request.WebAuthenticationDetail.UserCredential = new WebAuthenticationCredential();
            request.WebAuthenticationDetail.UserCredential.Key = "XXX-KEY-XXX"; // Replace "XXX" with the Key
            request.WebAuthenticationDetail.UserCredential.Password = "XXX-PWD-XXX"; // Replace "XXX" with the Password
            //
            request.ClientDetail = new ClientDetail();
            request.ClientDetail.AccountNumber = "XXX-ACCT#-XXX"; // Replace "XXX" with client's account number
            request.ClientDetail.MeterNumber = "XXX-MTR#-XXX"; // Replace "XXX" with client's meter number
            //
            request.TransactionDetail = new TransactionDetail();
            request.TransactionDetail.CustomerTransactionId = "***Address Validation v2 Request using VC#***"; // This is just an echo back 
            //
            request.Version = new VersionId(); // Creates the Version element with all child elements populated
            //
            request.RequestTimestamp = DateTime.Now;
            //
            request.Options = new AddressValidationOptions();
            request.Options.CheckResidentialStatus = true;
            request.Options.CheckResidentialStatusSpecified = true;
            request.Options.VerifyAddresses = true;
            request.Options.MaximumNumberOfMatches = "5";
            request.Options.StreetAccuracy = AddressValidationAccuracyType.MEDIUM;
            request.Options.DirectionalAccuracy = AddressValidationAccuracyType.MEDIUM;
            request.Options.CompanyNameAccuracy = AddressValidationAccuracyType.MEDIUM;
            request.Options.ConvertToUpperCase = true;
            request.Options.RecognizeAlternateCityNames = true;
            request.Options.ReturnParsedElements = true;
            //
            request.AddressesToValidate = new AddressToValidate[2];
            request.AddressesToValidate[0] = new AddressToValidate();
            request.AddressesToValidate[0].AddressId = "Kimmel";
            request.AddressesToValidate[0].Address = new Address();
            request.AddressesToValidate[0].Address.StreetLines = new String[1] { "425 Morningside Dr" };
            request.AddressesToValidate[0].Address.City = "Deerfield";
            request.AddressesToValidate[0].Address.PostalCode = "53531";
            request.AddressesToValidate[0].Address.CountryCode = "US";
            //
            request.AddressesToValidate[1] = new AddressToValidate();
            request.AddressesToValidate[1].AddressId = "WD";
            request.AddressesToValidate[1].Address = new Address();
            request.AddressesToValidate[1].Address.StreetLines = new String[1] { "2830 Progress Rd" };
            request.AddressesToValidate[1].Address.PostalCode = "53716";
            request.AddressesToValidate[1].CompanyName = "Wingra Direct";

The outbound SOAP Request (obtained using Fiddler). Note the missing options:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    <soap:Body>
        <AddressValidationRequest xmlns="http://fedex.com/ws/addressvalidation/v2"&gt;
            <WebAuthenticationDetail>
                <UserCredential>
                    <Key>XXX-KEY-XXX</Key>
                    <Password>XXX-PWD-XXX</Password>
                </UserCredential>
            </WebAuthenticationDetail>
            <ClientDetail>
                <AccountNumber>XXX-ACCT#-XXX</AccountNumber>
                <MeterNumber>XXX-MTR#-XXX</MeterNumber>
            </ClientDetail>
            <TransactionDetail>
                <CustomerTransactionId>***Address Validation v2 Request using VC#***</CustomerTransactionId>
            </TransactionDetail>
            <Version>
                <ServiceId>aval</ServiceId>
                <Major>2</Major>
                <Intermediate>0</Intermediate>
                <Minor>0</Minor>
            </Version>
            <RequestTimestamp>2010-08-26T16:40:13.2026134-05:00</RequestTimestamp>
            <Options>
                <CheckResidentialStatus>true</CheckResidentialStatus>
                <MaximumNumberOfMatches>5</MaximumNumberOfMatches>
            </Options>
            <AddressesToValidate>
                <AddressId>Kimmel</AddressId>
                <Address>
                    <StreetLines>425 Morningside Dr</StreetLines>
                    <City>Deerfield</City>
                    <PostalCode>53531</PostalCode>
                    <CountryCode>US</CountryCode>
                    <Residential>true</Residential>
                </Address>
            </AddressesToValidate>
            <AddressesToValidate>
                <AddressId>WD</AddressId>
                <CompanyName>Wingra Direct</CompanyName>
                <Address>
                    <StreetLines>2830 Progress Rd</StreetLines>
                    <PostalCode>53716</PostalCode>
                </Address>
            </AddressesToValidate>
        </AddressValidationRequest>
    </soap:Body>
</soap:Envelope>

The response I get back is:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    <env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"/&gt;
    <soapenv:Body>
        <v2:AddressValidationReply xmlns:v2="http://fedex.com/ws/addressvalidation/v2"&gt;
            <v2:HighestSeverity>SUCCESS</v2:HighestSeverity>
            <v2:Notifications>
                <v2:Severity>SUCCESS</v2:Severity>
                <v2:Source>wsi</v2:Source>
            </v2:Notifications>
            <v2:TransactionDetail xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
                <v2:CustomerTransactionId>***Address Validation v2 Request using VC#***</v2:CustomerTransactionId>
            </v2:TransactionDetail>
            <v2:Version xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
                <v2:ServiceId>aval</v2:ServiceId>
                <v2:Major>2</v2:Major>
                <v2:Intermediate>0</v2:Intermediate>
                <v2:Minor>0</v2:Minor>
            </v2:Version>
            <v2:ReplyTimestamp>2010-08-26T21:40:14.140Z</v2:ReplyTimestamp>
            <v2:AddressResults>
                <v2:AddressId>Kimmel</v2:AddressId>
                <v2:ProposedAddressDetails>
                    <v2:Score>93</v2:Score>
                    <v2:Changes>MODIFIED_TO_ACHIEVE_MATCH</v2:Changes>
                    <v2:ResidentialStatus>UNAVAILABLE</v2:ResidentialStatus>
                    <v2:DeliveryPointValidation>CONFIRMED</v2:DeliveryPointValidation>
                    <v2:Address>
                        <v2:StreetLines>425 Morningside Dr</v2:StreetLines>
                        <v2:City>Deerfield</v2:City>
                        <v2:StateOrProvinceCode>WI</v2:StateOrProvinceCode>
                        <v2:PostalCode>53531-9492</v2:PostalCode>
                        <v2:CountryCode>US</v2:CountryCode>
                    </v2:Address>
                    <v2:RemovedNonAddressData/>
                </v2:ProposedAddressDetails>
            </v2:AddressResults>
            <v2:AddressResults>
                <v2:AddressId>WD</v2:AddressId>
                <v2:ProposedAddressDetails>
                    <v2:Score>93</v2:Score>
                    <v2:Changes>MODIFIED_TO_ACHIEVE_MATCH</v2:Changes>
                    <v2:ResidentialStatus>UNAVAILABLE</v2:ResidentialStatus>
                    <v2:DeliveryPointValidation>CONFIRMED</v2:DeliveryPointValidation>
                    <v2:CompanyName>Wingra Direct</v2:CompanyName>
                    <v2:Address>
                        <v2:StreetLines>2830 Progress Rd</v2:StreetLines>
                        <v2:City>Madison</v2:City>
                        <v2:StateOrProvinceCode>WI</v2:StateOrProvinceCode>
                        <v2:PostalCode>53716-3338</v2:PostalCode>
                        <v2:CountryCode>US</v2:CountryCode>
                    </v2:Address>
                    <v2:RemovedNonAddressData/>
                </v2:ProposedAddressDetails>
            </v2:AddressResults>
        </v2:AddressValidationReply>
    </soapenv:Body>
</soapenv:Envelope>
+2  A: 

It appears that on option is ignored unless you also set the optionSpecified flag to true also.

Here is my new options code that works - the key being that you need to add the Options.(property)specified = true for each one you want:

    request.Options = New AddressValidationOptions()
    request.Options.CheckResidentialStatus = True
    request.Options.CheckResidentialStatusSpecified = True
    request.Options.VerifyAddresses = True
    request.Options.VerifyAddressesSpecified = True
    request.Options.MaximumNumberOfMatches = 5
    request.Options.StreetAccuracy = AddressValidationAccuracyType.MEDIUM
    request.Options.DirectionalAccuracy = AddressValidationAccuracyType.MEDIUM
    request.Options.CompanyNameAccuracy = AddressValidationAccuracyType.MEDIUM
    request.Options.ConvertToUpperCase = True
    request.Options.ConvertToUpperCaseSpecified = True
    request.Options.RecognizeAlternateCityNames = True
    request.Options.RecognizeAlternateCityNamesSpecified = True
    request.Options.ReturnParsedElements = True
    request.Options.ReturnParsedElementsSpecified = True
J. Clay
@J.Clay: Please read the [FAQ](http://stackoverflow.com/faq). This is not a discussion forum, so we don't reply to threads. If you have a question, ask it separately. If you have a comment, add a comment. Please don't add an answer that doesn't answer the question.
John Saunders
I would have added a comment, but apparently my reputation level won't allow it and this was the only option I have. I have just found the solution and will edit my answer so that it has the solution.
J. Clay
tried adding request.Options.CheckResidentialStatusSpecified, and that flag is at least being set in the outgoing SOAP request. This also triggers a ProposedAddressDetails element to be returned in the SOAP response. Unfortunately, I am getting unavailable for all the residential statuses.
Sam
@Sam: Just added some code to my answer, maybe that will clarify and help.
J. Clay
Getting closer. I'll have to try the VB.Net version to see if it makes a difference? I wonder if the fact I'm using the Express versions of C#/VB.Net make a difference in the way the code for Web Reference is is generated?
Sam
A: 

I was unable to get the API working so I ended up manually coding the handling of SOAP requests and responses. Aside from the API not properly setting all the flags, I also found out that the FedEx DEV server was not returning the Residential Status, regardless of what the options were (confirmed by our FedEx Web Services contact). When we gained access to the production servers the new code worked like a charm.

Sam
I am surprised you were able to get anything working on the Dev servers. I was told that Address Validation was not available on the test servers and was not able to do anything w/it until I got on the production servers. I couldn't even get the authentication to work on the test servers.
J. Clay