C# Rest API

Hi,

This what vendor provided to test

Error is :

The remote server returned an error: (401) Unauthorized.

My code

string result = string.Empty;
            try
            {
                // Create Request
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://api.verilocation.com/public/v1/drivers?id=1093609330685010");
                req.Method = "GET";
                // Create Client
                WebClient client = new WebClient();
                req.ContentType ="application/json; charset=utf-8";
               // req.UseDefaultCredentials = true;
               // req.PreAuthenticate = true;
               // req.Credentials = CredentialCache.DefaultCredentials;

                //req.ContentLength=61;


                req.Credentials = new NetworkCredential("xxx", "xxx111");
               
                   req.Headers.Add("Authorization","Bearer  Y2xpdmUuaG9sZGVuQHN0b25laGFyZHkuY28udWs6bDBnMTV0MWM1");
             //   req.Headers.Add("Authorization","Basic Y2xpdmUuaG9sZGVuQHN0b25laGFyZHkuY28udWs6bDBnMTV0MWM1");
                req.ProtocolVersion =HttpVersion.Version11;
            
                WebResponse response = req.GetResponse();
                string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
                MessageBox.Show(responseData.ToString());




              // Assign Credentials
               
                
            }
            catch (WebException ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

Open in new window



Response Class (Status 200)
ModelExample Value


GET /public/v1/drivers/{id}

{
  "Id": 0,
  "Name": "string",
  "Mobile": "string",
  "Status": 0,
  "Username": "string",
  "Password": "string",
  "Email": "string",
  "ButtonId": "string"
}



curl -X GET --header 'Accept: application/json' --header 'Authorization: Basic Y2xpdmUuaG9sZGVuQHN0b25laGFyZHkuY28udWs6bDBnMTV0MWM1' 'https://api.verilocation.com/public/v1/drivers/0'
Request URL
https://api.verilocation.com/public/v1/drivers/0
Response Body
{
  "Message": "Authorization has been denied for this request."
}
Response Code
401
Response Headers
{
  "date": "Wed, 01 Nov 2017 00:11:10 GMT",
  "www-authenticate": "Bearer",
  "server": "Microsoft-IIS/8.5",
  "x-aspnet-version": "4.0.30319",
  "x-powered-by": "ASP.NET",
  "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
  "content-type": "application/json; charset=utf-8",
  "access-control-allow-origin": "*",
  "cache-control": "no-cache",
  "access-control-allow-headers": "Authorization,Content-Type,X-Requested-With, Accept",
  "content-length": "61"
}
LVL 2
lankapalaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Miguel OzSoftware EngineerCommented:
401 UNAUTHORIZED
The request has not been applied because it lacks valid authentication credentials for the target resource.
Basically your credentials are not authorised to use the API. I will contact vendor for the correct username/ password and header Authorization that you should use for your case. If the the credentials are correct then they need to check user permissions to all your required functionality
0
Shaun VermaakTechnical SpecialistCommented:
Are you using a proxy?
0
lankapalaAuthor Commented:
No
0
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

Miguel OzSoftware EngineerCommented:
Have you contacted the vendor as suggested in my first comment?
0
lankapalaAuthor Commented:
yes,they said
"Looks like that username and password is working fine from our end:
I can only surmise the API isn’t being called correctly."
0
Miguel OzSoftware EngineerCommented:
Contact them again and send your code and the error details. 401 is a permission issue. Nothing to do with call unless you are not authorised to call this particular API feature. Ask them to run your code and whether they have OK response, Make sure they tell you which VS/.net framework version they are using as well just in case.
0
lankapalaAuthor Commented:
As they said, I change my coding,then no error message,Bu when i add records no error message,
Bu i can get all the details form the code, How to check the i have adding wwrites, when i trying to add nor error messages
0
Miguel OzSoftware EngineerCommented:
Please post post the vendor original code to compare with your existing code. Also include the documentation on how to use their API.
0
lankapalaAuthor Commented:
Vendor Code
public async Task<Jobs> CreateJob(int vehicleId, double latitude, double longitude, string destinationAddress
             , string destinationDescription, string destinationName, string message,int jobnumber
             
             
             
             )
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = this.baseUri;
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                    "Bearer",
                    this.userObject.access_token);

                var job = new Jobs
                {
                    
                    DestinationAddress = destinationAddress,
                    DestinationDescription = destinationDescription,
                    DestinationName = destinationName,
                    VehicleId = vehicleId,
                    DestinationLatitude = latitude,
                    DestinationLongitude = longitude,
                    Message = message,
                    Id = jobnumber
                };

                var content = new JavaScriptSerializer().Serialize(job);
                
                var response = await client.PostAsync(
                                   String.Format("/public/{0}/jobs",Version) ,
                                   new StringContent(content, Encoding.UTF8, "application/json"));

                var responseContent = await response.Content.ReadAsStringAsync();

                var id = 0;
                if ((response.StatusCode != HttpStatusCode.OK) ||
                    (responseContent == null) ||
                    (!int.TryParse(responseContent, out id)))
                {
                    return job;
                }

                job.Id = id;
                return job;
            }
        }

Open in new window


Calling
 try
            {
            string DestinationAddress = txtDestinationAddress.Text.ToString();
            string DestinationDescription = txtDestinationAddress.Text.ToString();
            double DestinationLatitude =Convert.ToDouble( txtLt.Text.ToString());
            double DestinationLongitude = Convert.ToDouble(txtLong.Text.ToString());
            string DestinationName = txtdetname.Text.ToString();
            string Message = txtMsg.Text.ToString();
            int jobNumber =Convert.ToInt32( txtJobNumber.Text.ToString());
            var c = new Client();
           c.SetCredentials("tttt", "ascc");
            
            Task.Run(
              async () =>
              {
//int vehicleId, double latitude, double longitude, string destinationAddress
           //  , string destinationDescription, string destinationName, string message,int jobnumber
                  
                  await c.Login();
                  var job = await c.CreateJob(Convert.ToInt32(txtvehicleid.Text.ToString()), DestinationLatitude, DestinationLongitude, DestinationAddress, DestinationDescription, DestinationName, Message, jobNumber);
                  MessageBox.Show("Added"+String.Format("Vehicle ID {0},Message{1},Job Number {2}" ,job.VehicleId,job.Message,job.Id));
                  
   }
          ).GetAwaiter().GetResult();


            }
            catch (WebException ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

Open in new window

0
Miguel OzSoftware EngineerCommented:
This is not the whole code - please post the whole sample code, but I can see some issues:
1) You do require a login call (c.Login();)
2) Where is this value assigned?
this.userObject.access_token

Open in new window

Notice that tokens are recalculated every time your program logs in, thus a token yesterday is not valid today depending on expiry policies.
3) Is Version = v1?
4) Api is expecting a POST not a GET. (PostAsync)

Thus, your initial sample code will not work because your  credentials and token are not valid. Your code must use the same construct
 var client = new HttpClient()

Open in new window

If you like you could make synchronous calls but you are better off using similar code:
public async Task<string> GetDriverDetails(string driverId)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = this.baseUri;
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                    "Bearer",
                    this.userObject.access_token);

                var response = await client.GetAsync(
                                   String.Format("/public/{0}/drivers?id=",Version, driverId));

                var responseContent = await response.Content.ReadAsStringAsync();

                return responseContent;
            }
        }

Open in new window


and change:
   await c.Login();
   var job = await c.CreateJob(Convert.ToInt32(txtvehicleid.Text.ToString()), DestinationLatitude, DestinationLongitude, DestinationAddress, DestinationDescription, DestinationName, Message, jobNumber);
   MessageBox.Show("Added"+String.Format("Vehicle ID {0},Message{1},Job Number {2}" ,job.VehicleId,job.Message,job.Id));

Open in new window

with:            
   await c.Login();
   var result = await c.GetDriverDetails("1093609330685010");
   MessageBox.Show("My results are"+ result);

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ukerandiCommented:
Hi Miguel Oz, I need to accept your answer but there is no button
0
lankapalaAuthor Commented:
thx
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.