I am developing a Blazor server-side application.
The api call generates and downloads a pdf file.
No error is displayed on the client side but I can see from the server logs that the API call is not being processed. The only error message I can identify is StatusCode: 415, ReasonPhrase: Unsupported Media Type, Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers.
GetAsync is working fine
var response = await _httpClient.GetAsync($"xxx/yyyyy/zzzzz");
The only significant issue I have for now is with serialisation and deserialisation using the new System.Text.Json.Serialization and for now I have worked around this by developing my own serialisation and deserialisation routines which work fine and I will use them until I have resolved the issues with System.Text.Json.Serialization.
My question relates to PostAsynch which I cannot get to work. I am using Basic Authentication for now and sending a JSON body. I am calling APIs which are live and have been working fine with other applications calling them. They also work fine in Postman, I just cannot get them to work with Blazor.
//The relevant Startup code is as follows
services.AddHttpClient<Services.ApiServicerw>(client =>
{
client.BaseAddress = new Uri("https://www.xxxxxxxxxx.com");
});
//The code in the .razor page is as follows
#page "/runreport2"
#using BlazorApp1.Services
#inject ApiServicerw ApiService1
#using System.IO
<h1>Report</h1>
<p>This component demonstrates running a report</p>
#code {
protected override async Task OnInitializedAsync()
{
var fresult = await ApiService1.GetContactsAsync();
}
}
//An extract of the code in the Services class is as follows
_httpClient.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue("Basic", encoded);
var stringContent = new StringContent(jsonString);
_httpClient.DefaultRequestHeaders.Accept.Add(new
System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var response = await _httpClient.PostAsync($"api/xxxx/yyyyyy",stringContent);
I have resolved this. I needed to change this line as follows
var stringContent = new StringContent(jsonString,System.Text.Encoding.UTF8, "application/json");
Related
Getting really irritated with this. The playground gives only python and node, trying to use this in C# and I keep getting errors. Here is how I have it setup.
First in the Program / Startup file, I am setting it up like so: (URL: https://api.openai.com/)
services.AddHttpClient("ChatGptAPI", client =>
{
client.DefaultRequestHeaders.Clear();
client.BaseAddress = aiOptions.Url;
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + aiOptions.Bearer);
});
Then in my method, I am calling this:
var client = _httpFactory.CreateClient("ChatGptAPI");
var payload = new
{
prompt = $"Create a first person story\n\n{storyText}",
temperature = "0.5",
max_tokens = "1500",
model = "text-davinci-003"
};
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.PostAsync("v1/completions", content);
Console.WriteLine("ChatGptAPI result:");
Console.WriteLine(response.RequestMessage);
I at first I kept getting Bad Request errors, but once I tried other URLs for the request, it appears to go through, but the response is blank.
For the life of me, I cannot find any samples out there that has C# calling these services.
Any help would be great.
I have tried multiple URLs, I've tried running this in Playground and view code and I've searched for other samples, but this keeps failing or returning nothing. Also tried using the OpenAI Nuget package, that was a waste of time.
If you are actually managing to reach the completions endpoint and you have a valid key then you are just reading the wrong object back.
After you get your response you should read it, something like:
var gptResponse = await response.Content.ReadAsStringAsync();
you can then parse or better deserialize the API response
I'm not sure there is anything wrong with my code, but I have a dll .net 4.8 library file that is hooked up to an ERP system that makes REST calls to a third party web based app that is unix-based. We are troubleshooting an issue regarding a strange error but something else came up where they said they are getting a lot of GET statements from the dll for URLs that require PATCH/POST and those urls (specifically one) doesn't have functionality set up for a GET statement.
Is is possible that the .NET objects are sending underlying HTTP calls?
So basically, I would like to log all of the REST statements that are being sent to verify, if possible, where they are coming from. I've combed my code and there is literally one entry point to this statement and I am sending a PATCH and the resource url doesn't require anything to be sent in the body except an empty string.
So is there a way to log all the HTTP calls going out from my project? See code below for my routine.
I've looked up how to log and I mostly get results for web projects, but this is a dll project and I'm not sure if those suggestions will work for this.
try
{
CVToken curToken = CVGlobalRestCalls.GetToken(Session);
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", curToken.Token);
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var jSettings = new JsonSerializerSettings();
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("PATCH"), string.Format("{0}/readytosend/{1}/complete", Globals.GetRESTURL(Session), JobID));
request.Content = new StringContent(JsonConvert.SerializeObject(string.Empty, Formatting.Indented, jSettings), Encoding.Default, "application/json-patch+json");
HttpResponseMessage response = httpClient.SendAsync(request).Result;
CVJob cvCompletedJob = JsonConvert.DeserializeObject<CVJob>(CVGlobalRestCalls.GetResponseContent(response));
outFile.WriteLine(string.Format("Invoice Group {0} has been pushed to CV", JobID.ToString()));
}
catch (Exception ex)
{
throw new Exception(string.Format(" {0}", ex.Message));
}
I am working in an internal corporate environment. We have created a webapi installed on iis on port 85. We call this from another MVC HelperApp on port 86. It all works as expected. Now we want to tighten security and add an SSL cert to iis on port 444 and bind it to our API.
Initially we test it with Postman, SoapUI, and a C# console app and it all works. Now we try calling it from our MVC HelperApp and it returns a 404 sometimes.
Deeper debugging; I put the code into a C# DLL (see below). Using the console app I call the Dll.PostAPI and it works as expected. Now I call that same Dll.PostAPI from the MVC HelperApp and it won't work. When I step through the code I make it as far as this line await client.PostAsync(url, data); and the code bizarrely ends, it doesn't return and it doesn't throw an exception. Same for Post and Get. I figure it makes the call and nothing is returned, no response and no error.
Also, if I change the url to "https://httpbin.org/post" or to the open http port85 on iss it will work. I have concluded that the C# code is not the problem (but I'm open to being wrong).
Therefore I have come to the conclusion that for some reason the port or cert is refusing calls from browsers.
We are looking at:
the "Subject Alternative Name" but all the examples show
WWW.Addresses which we are not using.
the "Friendly Name" on the cert creation.
and CORS Cross-Origin Resource Sharing.
These are all subjects we lack knowledge in.
This is the calling code used exactly the same in the console app and the web app:
var lib = new HttpsLibrary.ApiCaller();
lib.makeHttpsCall();
This is what's in the DLL that gets called:
public async Task<string> makeHttpsCall()
{
try
{
List<Quote> quotes = new List<Quote>();
quotes.Add(CreateDummyQuote());
var json = JsonConvert.SerializeObject(quotes);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var url = "https://httpbin.org/post"; //this works in Browser
//url = "https://thepath:444//api/ProcessQuotes"; //444 DOES NOT WORK in browsers only. OK in console app.
//url = "http://thepath:85/api/ProcessQuotes"; //85 works.
var client = new HttpClient();
var response = await client.PostAsync(url, data); //<<<this line never returns when called from browser.
//var response = await client.GetAsync(url); //same outcome for Get or Post
var result = await response.Content.ReadAsStringAsync();
return result;
}
catch (Exception ex)
{
throw;
}
}
I have used visual studio 2019. I have used 2 API calls
I referred to the document below:
Use Kudu API to change function.json https://github.com/projectkudu/kudu/wiki/REST-API
1.PUT https://{functionAppName}.scm.azurewebsites.net/api/vfs/{pathToFunction.json}, Headers: If-Match:"*", Body: new function.json content
Then send the request to apply changes
2.POST https://{functionAppName}.scm.azurewebsites.net/api/functions/synctriggers
Both apis are return success status code
status code:
API1 gives 204 or 201 which means the document successfully updated
API2 gives 201 which means the document successfully done the sync trigger to save the file modification
after the function is completed then I refresh the page the file is not changed
code below:
using (var client = new HttpClient())
{
var creds = "credentials";
var credentials = Encoding.ASCII.GetBytes(creds);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(credentials));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation("If-Match", "*");
var data = new List<ChangeData>
{
new ChangeData{schedule="125255"}
};
string json = "{'schedule':'*/48 * * * * *'}";
var customerJson = JsonConvert.SerializeObject(data);
var content = new StringContent(customerJson, Encoding.UTF8, "application/json");
var response = client.PutAsync("https://********.scm.azurewebsites.net/api/vfs/home/site/wwwroot/Function7/function.json", content);
Console.WriteLine(response.Result);
/// var errorMessage = response..ToString();
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://******.scm.azurewebsites.net/api/functions/synctriggers"))
{
var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("basestring"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
var response3 = await client.SendAsync(request);
Console.WriteLine(response3);
}
I want to change schedule value in the function.json
Newest
The previous version of azure function can modify the file through the run-from-package configuration. Now the function app directly released through vs2019 does not support this operation.
To achieve your needs, we can use the command line to publish. The specific steps are in your other post, you need to help more forum users.
func azure functionapp publish function_app_name --csharp --nozip --force
How to change content dynamically after function is called in Azure function app
You want to change schedule value in the function.json.
As I replied in another post of yours, it doesn't make sense, but I also have a way( by SCM_DO_BUILD_DURING_DEPLOYMENT) for you to make changes.
The main reason is that modifying the json file will not recompile our FunctionApp1.dll file, as shown in the figure below.
How to change content dynamically after function is called in Azure function app
Why do you have such a demand?
I guess you have created a Function App on Azure Portal, so you think you can modify the configuration by modifying function.json, but this is not the case.
Because the function app created on the portal generates a .csx file, it does not end up running a .dll, which is the essential difference.
I have two ASP.NET Core 2.1 apps and I'm trying to make a simple POST call from one app to the other using HttpClient.
For some reason, when I use [FromBody] to get the simple text I'm trying receive, I get a BadRequest error.
Here's my code on the sender. First, this is what's in my ConfigureServices method. I'm using the new HttpClientFactory feature in ASP.NET Core 2.1. I also created a client class named myApiCallerClient that handles my API calls:
services.AddHttpClient("myNamedClient", client =>
{
client.BaseAddress = new Uri("http://localhost:50625/api/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
services.AddScoped(x => {
var httpClientFactory = x.GetRequiredService<System.Net.Http.IHttpClientFactory>();
var myApiCallerClient = httpClientFactory.CreateClient("myNamedClient");
return new Clients.ApiCaller.ApiCallerClient(myApiCallerClient);
});
Here's the code in myApiCallerClient:
public async Task SayHello()
{
var response = await _httpClient.PostAsync("test", new StringContent("Saying hello!", System.Text.Encoding.UTF8, "text/plain"));
}
And here's my code on the receiving end which is the POST() API method in TestController:
[HttpPost]
public async Task Post([FromBody]string input)
{
// Some logic
}
My call doesn't hit this method if I use [FromBody] and I get BadRequest error on the sender. If I use [FromHeader] my request hits this API method but I'm getting a null value.
What am I doing wrong here?
ASP.NET Core doesn't support a Content-Type of text/plain out of the box, so the server is rejecting your request as it's not something that it can parse when using the [FromBody] attribute.
In the comments, you said:
Ultimately I won't be sending text. My main concern here is that I'm not hitting my API method. [...] Once I make sure everything is working, I'll be sending JSON data which will get deserialized on the receiving end.
In order to test whether the problem is due to the text/plain Content-Type, you can update your PostAsync line to something like this:
var response = await _httpClient.PostAsync(
"test",
new StringContent("\"Saying hello!\"", System.Text.Encoding.UTF8, "application/json"));
As application/json is a supported Content-Type by default, the code above uses that and wraps the value you were sending with "s in order to make it a valid JSON value.