An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set. trying to consuming a webservice
Solution 1
BaseAddress is there so that you can make all the calls relative to the the BaseAddress. It works, you just need to know some of the idiosyncrasies of BaseAddress Why is HttpClient BaseAddress not working?
But your problem is that you are instantiating a new HttpClient in each method.
static async Task<Uri> CreateCustomerAsync(Customer customer)
{
HttpClient client = new HttpClient();
//you never set the BaseAddress
//or the authentication information
//before making a call to a relative url!
HttpResponseMessage response = await client.PostAsJsonAsync("api/customers/1?output_format=JSON", customer);
response.EnsureSuccessStatusCode();
// return URI of the created resource.
return response.Headers.Location;
}
A better way would be to wrap the HttpClient call in a class and it up in the constructor, then share it in any of your methods
public WrapperClass(Uri url, string username, string password, string proxyUrl = "")
{
if (url == null)
// ReSharper disable once UseNameofExpression
throw new ArgumentNullException("url");
if (string.IsNullOrWhiteSpace(username))
// ReSharper disable once UseNameofExpression
throw new ArgumentNullException("username");
if (string.IsNullOrWhiteSpace(password))
// ReSharper disable once UseNameofExpression
throw new ArgumentNullException("password");
//or set your credentials in the HttpClientHandler
var authenticationHeaderValue = new AuthenticationHeaderValue("Basic",
// ReSharper disable once UseStringInterpolation
Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", username, password))));
_httpClient = string.IsNullOrWhiteSpace(proxyUrl)
? new HttpClient
{
DefaultRequestHeaders = { Authorization = authenticationHeaderValue },
BaseAddress = url
}
: new HttpClient(new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Address = new Uri(proxyUrl),
BypassProxyOnLocal = false,
UseDefaultCredentials = true
}
})
{
DefaultRequestHeaders = { Authorization = authenticationHeaderValue },
BaseAddress = url
};
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.AcceptEncoding.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<Member> SomeCallToHttpClient(string organizationId)
{
var task = await _httpClient.GetStringAsync(<your relative url>));
return JsonConvert.DeserializeObject<SomeType>(task,
new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver()});
}
Solution 2
I bet you need the complete url address. The url is not relative to the caller when using HttpClient.
static async Task<Uri> CreateCustomerAsync(Customer customer)
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsJsonAsync("http://www.fullyqualifiedpath.com/api/customers/1?output_format=JSON", customer);
response.EnsureSuccessStatusCode();
// return URI of the created resource.
return response.Headers.Location;
}
Related videos on Youtube
Zero One
Updated on June 04, 2022Comments
-
Zero One almost 2 years
I am trying to Consume a Web Service using HttpClient in .NET and after i did all steps mentioned in msdn
o Get the following exception : An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.
here is my class
public class Customer { public int id { get; set; } public string id_default_group { get; set; } public string id_lang { get; set; } public string newsletter_date_add { get; set; } public string ip_registration_newsletter { get; set; } public string last_passwd_gen { get; set; } public string secure_key { get; set; } public string deleted { get; set; } public string passwd { get; set; } public string lastname { get; set; } public string firstname { get; set; } public string email { get; set; } public string id_gender { get; set; } public string birthday { get; set; } public string newsletter { get; set; } public string optin { get; set; } public string website { get; set; } public string company { get; set; } public string siret { get; set; } public string ape { get; set; } public string outstanding_allow_amount { get; set; } public string show_public_prices { get; set; } public string id_risk { get; set; } public string max_payment_days { get; set; } public string active { get; set; } public string note { get; set; } public string is_guest { get; set; } public string id_shop { get; set; } public string id_shop_group { get; set; } public string date_add { get; set; } public string date_upd { get; set; } public string reset_password_token { get; set; } public string reset_password_validity { get; set; } } class Program { static void ShowProduct(Customer customer) { Console.WriteLine($"Email: {customer.email}\tFirst Name: {customer.firstname}"); } static async Task<Uri> CreateCustomerAsync(Customer customer) { HttpClient client = new HttpClient(); HttpResponseMessage response = await client.PostAsJsonAsync("api/customers/1?output_format=JSON", customer); response.EnsureSuccessStatusCode(); // return URI of the created resource. return response.Headers.Location; } static void Main() { RunAsync().Wait(); } static async Task RunAsync() { NetworkCredential hd = new NetworkCredential("INHFTLZLMLP1TUTJE7JL9LETCCEW63FN", ""); HttpClientHandler handler = new HttpClientHandler {Credentials = hd }; HttpClient client = new HttpClient(handler); client.BaseAddress = new Uri("http://localhost:8080/newprestashop/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); try { Customer customer = new Customer(); var url = await CreateCustomerAsync(customer); // Get the product customer = await GetProductAsync(url.PathAndQuery); ShowProduct(customer); } catch (Exception e) { Console.WriteLine(e.Message); } Console.ReadLine(); } static async Task<Customer> GetProductAsync(string path) { Customer customer = null; HttpClient client = new HttpClient(); HttpResponseMessage response = await client.GetAsync(path); if (response.IsSuccessStatusCode) { customer = await response.Content.ReadAsAsync<Customer>(); } return customer; } }
}
-
Mitch Stewart almost 7 yearsAre you sure your web service is up and running at localhost:8080? I would launch the web api project and add a break point at the start of the method (index) of the controller (newprestashop) you are trying to hit. Then, make your call from your client.
-
Zero One almost 7 yearsi test in post man it work great
-
-
Zero One almost 7 yearsworks great the exception is gone but it gives another " Response status code does not indicate success: 401 (Unauthorized)."
-
Ross Bush almost 7 yearsThat means you need to authenticate prior to making your api call. The endpoint was reached and rejected due to lack of authorization.
-
Fran almost 7 yearsYour authorization problem is the same problem as your BaseAddress one. you instantiate HttpClient and never set the values. See my answer.
-
Ross Bush almost 7 yearsI would actually give the answer to @Fran. I solved your immediate problem, however, his answer solves with a better overall solution.