My ASP.NET MVC project used HttpClient.PostAsync() to post to a webAPI endpoint. All is fine until I recently upgraded the project to target .NET Framework 4.7.2. Now the call will end with HTTP Status 405 (Method not allowed). However, endpoints with [HTTPGet] work. In a desperate measure, I set the API controller with [EnableCors(origins: "", headers: "", methods: "*")] and call the endpoint with the same domain and port (localhost to localhost). I even reverted the project to 4.6.1. It still throws 405 error. Could you help? Thank you.
public static async Task < T > Post < T > (string baseUrl, string urlSegment, HttpContent postContent) {
string responseContent = string.Empty;
Uri returnUrl = null;
using(HttpClient client = GetClient(baseUrl)) {
HttpResponseMessage response = await client.PostAsync(urlSegment.TrimStart('/'), postContent).ConfigureAwait(false);
if (response.IsSuccessStatusCode) {
returnUrl = response.Headers.Location;
}
return JsonConvert.DeserializeObject < T > (returnUrl.ToString());
}
}
It turned out that the WebAPI endpoint path has been changed. In addition, I reverted the GIT commit to rollback to a version before I upgrade to DotNet Framework 4.7.2, then cherry-picked all the commits after the 4.7.2 upgrade.
Related
I'm trying to make HTTP requests via a WebProxy in a .net core 2.0 web application. The code I've got works fine in .net framework so I know (believe) its not an environmental issue. I've also tried to make the request using both HttpWebRequest and HttpClient but both mechanisms always result in 407 (Proxy Authentication Required) http error in .net core. Its as if in .net core the credentials I'm supplying are always being ignored.
Here is the code I've been using:
public void Test()
{
var cred = new NetworkCredential("xxxxx", "yyyyyy");
var proxyURI = new Uri("http://xxx.xxx.xxx.xxx:80");
var destinationURI = new Uri("http://www.bbc.co.uk");
WebProxy proxy = new WebProxy(proxyURI, false) { UseDefaultCredentials = false, Credentials = cred };
MakeProxyRequestViaHttpWebRequest(proxy, destinationURI);
MakeProxyRequestViaHttpClient(proxy, destinationURI);
}
private void MakeProxyRequestViaHttpClient(WebProxy proxy, Uri destination)
{
HttpClientHandler handler = new HttpClientHandler()
{
Proxy = proxy,
UseProxy = true,
PreAuthenticate = true,
UseDefaultCredentials = false
};
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = client.GetAsync(destination).Result;
if (response.IsSuccessStatusCode)
{
HttpContent content = response.Content;
string htmlData = content.ReadAsStringAsync().Result;
}
else
{
HttpStatusCode code = response.StatusCode;
}
}
private void MakeProxyRequestViaHttpWebRequest(WebProxy proxy, Uri destination)
{
HttpWebRequest req = HttpWebRequest.Create(destination) as HttpWebRequest;
req.UseDefaultCredentials = false;
req.Proxy = proxy;
req.PreAuthenticate = true;
using (WebResponse response = req.GetResponse())
{
using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
{
string htmlData = responseStream.ReadToEnd();
}
}
}
I've tried the following in .net core but the result is always 407:
Run the code in a console app
Implement IWebProxy and use that as the proxy
Set default values for other properties on WebProxy, HttpClient, etc. (removed on the example above because it works fine on .net standard)
I've run out of ideas and things to try. I have the following questions:
Does the code need to be different between .net core vs .net framework
Are there additional things that need to go into appsettings.json (ie. the config that would have gone into web.config)
Is there any additional configuration code required in Startup.cs
Should I be looking to use an external library
How would I trouble shoot what the issue is? Fiddler doesn't seem to be helping but then I haven't looked to hard at configuring it.
I am trying to make an HTTP GET call from a .NET Core 3.0 console application. The endpoint expects Windows Authentication. The endpoint is an in-production .NET Framework 4.5.2 Web API service on IIS successfully used by several client applications.
My test program succeeds for a net45 framework target. In contrast, the netcoreapp3.0 build receives a 401 Unauthorized.
Here is my method:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
static async Task<string> Get(string serverUri, string requestUri)
{
var handler = new HttpClientHandler() { UseDefaultCredentials = true };
var client = new HttpClient(handler) { BaseAddress = new Uri(serverUri) };
return await client.GetStringAsync(requestUri);
}
Here is my project file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net45;netcoreapp3.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="System.Net.Http" Version="4.3" />
</ItemGroup>
</Project>
Running .\bin\Debug\net45\HttpClientTest.exe returns the expected JSON result.
Running dotnet .\bin\Debug\netcoreapp3.0\HttpClientTest.dll receives a 401 Unauthorized.
Unhandled exception. System.AggregateException: One or more errors occurred. (Response status code does not indicate success: 401 (Unauthorized).)
---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at System.Net.Http.HttpClient.GetStringAsyncCore(Task`1 getTask)
at ConsoleApp1.Program.Get(String serverUri, String requestUri) in C:\temp\coreapp3\Program.cs:line 16
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at ConsoleApp1.Program.Main(String[] args) in C:\temp\coreapp3\Program.cs:line 22
How do I fix this?
I have also tried the variations below, without any change in output:
handler.Credentials = CredentialCache.DefaultNetworkCredentials;
handler.Credentials = CredentialCache.DefaultCredentials;
handler.Credentials = new NetworkCredential(username, password, domain);
This workaround works for me add this before creating HttpClient / Handler:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
So we are running into the same issue with HttpClient, but on the first request it is unauthorized, but if we do a another quick request call, it goes through just fine, and we get authorized.
If I do this on a .NET 4.7.1 console app, it works perfect. If I do it in a .NET 4.7.1 empty web app, it works fine, only if I do .NET Core 2.x do we get this issue.
var result = string.Empty;
var responseMessage = _client.GetAsync(url).Result;
if (responseMessage.IsSuccessStatusCode)
{
result = await responseMessage.Content.ReadAsStringAsync();
}
else
{
var responseMessage2 = _client.GetAsync(url).Result;
if (responseMessage2.IsSuccessStatusCode)
{
result = await responseMessage2.Content.ReadAsStringAsync();
}
}
return result;
The title says it all. I'm running asp core app in azure. I'm noticing that Request.Host only returns the subdomain portion.
Can't tell of this is an azure implementation issue or Kestrel or asp core.
For example the following controller running on [mysubdomain].azurewebsites.net
[Route("busted")]
public Dictionary<string, object> Index()
{
var dict = new Dictionary<string, object>();
dict.Add("Request.Host", Request.Host);
return dict;
}
would return
{
"Request.Host" : "mysubdomain"
}
I believe the issue was an azure configuration or something because the issue has resolved this morning without code changes.
I am working on a project built using ASP.Net Web API 2 and AngularJS. Everything works as expected when I run the project from Visual Studio. But after deploying the project in Local IIS server the API calls giving me this error
"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'
YES I have the following line in my WebAPIConfig file
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
And here's an example API method I am using
// GET api/PatientsAPI
[ResponseType(typeof(Patient))]
public IHttpActionResult GetPatients()
{
var patients = from patient in db.Patients
select new
{
id = patient.id,
name = patient.name,
contact = patient.contact
};
return Ok(patients);
}
I am trying to connect to Http Service using flex wizard
The server side is Asp.net MVC4 Web Api, I used the templates to create simple CRUD controller.
The problem is that test operation gives back: "InvocationTargetException:The URL is not valid" error message. I have seen that the problem is the http response status. If it is OK 200 then I dont have that problem. I can change the response status manually to OK in the controller, but why Flex cannot handle the default 204 response status from controller template?
This is the function from the server controller:
public HttpResponseMessage Postattributes(attributes attributes)
{
if (ModelState.IsValid)
{
db.attributes.Add(attributes);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, attributes);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = attributes.attId }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
if I change to HttpStatusCode.OK I do not get the error