HttpClient PutAsync not updating Web API - c#

I have a simple .Net Core Web API with some simple Get, post, put endpoints. I also created a simple Console Client to test the API. The get and post methods work fine although when I test the Put, it does not update the Web API with the new data. I have tested the Web API Put method with swagger and it works fine, so it seems like my Console App Client logic is incorrect. Can anyone see what I am doing wrong?
edit: weather is an in-memory collection - a List so I do not need to SaveChanges()
Console Client:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
namespace Lab1RestConsole
{
class Program
{
private static readonly HttpClient client = new HttpClient();
private static readonly String baseURI = "https://localhost:44347/api/Weather/";
static async Task RunAsync()
{
try
{
//1 GET /api/Weather/
var serializer = new DataContractJsonSerializer(typeof(List<WeatherInformation>));
var streamTask = client.GetStreamAsync(baseURI);
var entries = serializer.ReadObject(await streamTask) as List<WeatherInformation>;
foreach (var e in entries)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("");
//2 GET /api/Weather/
serializer = new DataContractJsonSerializer(typeof(List<WeatherInformation>));
streamTask = client.GetStreamAsync(baseURI + "warning/false");
entries = serializer.ReadObject(await streamTask) as List<WeatherInformation>;
foreach (var e in entries)
{
Console.WriteLine(e.ToString());
}
//3 GET /api/Weather/city/Dublin
serializer = new DataContractJsonSerializer(typeof(WeatherInformation));
streamTask = client.GetStreamAsync(baseURI + "city/Dublin");
WeatherInformation weatherinfo = serializer.ReadObject(await streamTask) as WeatherInformation;
Console.WriteLine("\n" + weatherinfo + "\n");
// serialise to JSON
weatherinfo = new WeatherInformation() { City = "Antwerp", Temp = 3, Warning = true, WeatherType = 0, WindSpeed = 22 }; ;
MemoryStream ms = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeatherInformation));
ser.WriteObject(ms, weatherinfo);
// read and create string content for POST
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
StringContent content = new StringContent(sr.ReadToEnd(), Encoding.UTF8, "application/json");
//4 POST - add new city
HttpResponseMessage httpResponse = await client.PostAsync(baseURI, content);
httpResponse.EnsureSuccessStatusCode();
//5 update PUT to api/Weather/Dublin - now temp is 10
weatherinfo = new WeatherInformation() { City = "Antwerp", Temp = 10, Warning = true, WeatherType = 0, WindSpeed = 22 }; ;
var putTask = client.PutAsync(baseURI + "Dublin", content);
}
catch (HttpRequestException e)
{
Console.WriteLine(e.Message);
}
}
static void Main()
{
RunAsync().Wait();
client.Dispose();
Console.ReadLine();
}
}
}
The Put action in Web API
// PUT: api/Weather/5
[HttpPut("{city}")]
public IActionResult PutUpdateCityWeather(string city, WeatherInformation weatherInfo)
{
if (ModelState.IsValid)
{
var record = weather.FirstOrDefault(e => e.City.ToUpper() == city.ToUpper());
if (record != null)
{
record.Temp = weatherInfo.Temp;
record.Warning = weatherInfo.Warning;
record.WeatherType = weatherInfo.WeatherType;
record.WindSpeed = weatherInfo.WindSpeed;
return Ok();
}
else
{
return BadRequest();
}
}
else
{
return BadRequest(ModelState);
}
}

Related

Response 400 on the post of httpclient in dotnet core

I am wrote the code to POST from my web application but it is sending 400 bad request.
See the my controller class:
[HttpPost]
public async Task<IActionResult> CreateAgent(AgentCreateDto agentCreateDto)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44331/api/");
var responseTask = client.PostAsJsonAsync("Agent/CreateAgent", agentCreateDto);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var newAgentAdd = JsonConvert.DeserializeObject<AgentCreateDto>(await result.Content.ReadAsStringAsync());
var newAgent = newAgentAdd;
TempData["SuccessMessage"] = $"Agent {newAgent.FirstName} was successfully created.";
return RedirectToAction("AgentLists");
//return RedirectToAction("GetAgentById", new { AgentId = newAgent.usersId});
}
}
return View();
}
Here is below the problem image please see for the reference.
Here is api code for that I am send the request:
[HttpPost("CreateAgent")]
public async Task<IActionResult> CreateAgent([FromForm]AgentCreateDto agentCreateDto)
{
if (!ModelState.IsValid)
{
return BadRequest("Invalid model object");
}
if (agentCreateDto.ProfileImage != null)
{
string uniqueFileName = UploadProfileImage(agentCreateDto.ProfileImage);
agentCreateDto.ProfileNewImage = uniqueFileName;
}
var createAgent = await _userService.CreateAgent(agentCreateDto);
//_logger.LogInformation($"User added to the for file test. ");
return Created("", new
{
Id = createAgent.UsersId,
Message = "Agent created Successfully",
Status = "Success",
UserType = createAgent.UserType
});
}
And for image uploading code at the API side:
private string UploadProfileImage(IFormFile ProfileImage)
{
string uniqueFileName = null;
if (ProfileImage != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.ContentRootPath, "ProfileImage");
uniqueFileName = Guid.NewGuid().ToString() + "_" + ProfileImage.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
ProfileImage.CopyTo(fileStream);
}
}
return uniqueFileName;
}
The correct way to post file and additional data by HttpClient like below:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44331/api/");
var formContent = new MultipartFormDataContent();
formContent.Add(new StringContent(agentCreateDto.Id.ToString()), nameof(agentCreateDto.Id));
formContent.Add(new StringContent(agentCreateDto.Message), nameof(agentCreateDto.Message));
formContent.Add(new StringContent(agentCreateDto.UserType), nameof(agentCreateDto.UserType));
//other proerties....
formContent.Add(new StreamContent(agentCreateDto.ProfileImage.OpenReadStream()), nameof(agentCreateDto.ProfileImage), Path.GetFileName(agentCreateDto.ProfileImage.FileName));
//change PostAsJsonAsync to PostAsync.....
var responseTask = client.PostAsync("/Agent/CreateAgent", formContent);
responseTask.Wait();
var result = responseTask.Result;
//more code...
}

Sending Multiple Files in a single Request to API

I am fairly new to API's. I am writing a "simple" API that will convert .docx files to .pdf files and return the pdf's back to the client for saving. I have the code working for a single file but I wanted to code the API to handle multiple files in a single request. Now the API is not receiving the request. I can provide the working code with a single file if requested.
I am sure I am missing something simple. Please see below and see if anyone see's something that I could be doing better or why the API is not receiving the POST request.
Client:
List<string> documents = new List<string>();
private async void btnConvert_Click(object sender, EventArgs e)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
//client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
foreach (string s in docPaths)
{
byte[] bte;
bte = File.ReadAllBytes(docPath);
string data = JsonConvert.SerializeObject(Convert.ToBase64String(bte));
documents.Add(data);
}
using (var formData = new MultipartFormDataContent())
{
foreach (string s in documents)
{
//add content to form data
formData.Add(new StringContent(s, Encoding.UTF8, "application/json"));
}
// List of Http Reponse Messages
var conversions = documents.Select(doc => client.PostAsync(BaseApiUrl + ApiUrl, formData)).ToList();
//Wait for all the requests to finish
await Task.WhenAll(conversions);
//Get the responses
var responses = conversions.Select
(
task => task.Result
);
foreach (var r in responses)
{
// Extract the message body
var s = await r.Content.ReadAsStringAsync();
SimpleResponse res = JsonConvert.DeserializeObject<SimpleResponse>(s);
if (res.Success)
{
byte[] pdf = Convert.FromBase64String(res.Result.ToString());
// Save the PDF here
}
else
{
// Log issue
}
}
}
}
API: This is not getting the request so this function is not complete. I need to figure out why it not being hit.
[HttpPost]
public async Task<List<SimpleResponse>> Post([FromBody]string request)
{
var response = new List<SimpleResponse>();
Converter convert = new Converter();
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var requestContents in provider.Contents)
{
try
{
//var result = convert.CovertDocToPDF(requestContents, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
//response.Add(new SimpleResponse() { Result = result, Success = true });
}
catch (Exception ex)
{
response.Add(new SimpleResponse() { Success = false, Exception = ex, Errors = new List<string>() { string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? "") } });
}
}
return response;
}
SimpleResponse Model:
public class SimpleResponse
{
public object Result { get; set; }
public bool Success { get; set; }
public Exception Exception { get; set; }
public List<string> Errors { get; set; }
}
UPDATE
Did suggestions made by #jdweng and I am getting a null response on the API POST
Client:
public async void btnConvert_Click(object sender, EventArgs e)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//application/json
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
List<string> requests = new List<string>();
byte[] bte;
// New Code per the suggestion
foreach (string s in docPaths)
{
bte = File.ReadAllBytes(s);
requests.Add(Convert.ToBase64String(bte));
}
// End new code
string data = JsonConvert.SerializeObject(requests);
request.Content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response1 = client.PostAsync(BaseApiUrl + ApiUrl, request.Content).Result;
Task<string> json = response1.Content.ReadAsStringAsync();
SimpleResponse response = JsonConvert.DeserializeObject<SimpleResponse>(json.Result);
//result = JsonConvert.DeserializeObject(result).ToString();
if (response.Success)
{
bte = Convert.FromBase64String(response.Result.ToString());
if (File.Exists(tempPdfPath))
{
File.Delete(tempPdfPath);
}
System.IO.File.WriteAllBytes(tempPdfPath, bte);
}
else
{
}
}
}
Server:
[HttpPost]
public async Task<List<SimpleResponse>> Post([FromBody]string request)
{
// The request in NULL....
List<SimpleResponse> responses = new List<SimpleResponse>();
List<string> resp = JsonConvert.DeserializeObject(request) as List<string>;
try
{
Converter convert = new Converter();
foreach (string s in resp)
{
var result = convert.CovertDocToPDF(request, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
responses.Add(new SimpleResponse()
{
Result = result,
Success = true
});
}
}
catch (Exception ex)
{
responses.Add(new SimpleResponse()
{
Result = null,
Success = true,
Exception = ex,
Errors = new List<string>() { string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? "") }
});
}
return responses;
}
I have finally solved the issues and can now successfully send multiple .docx files to the API and get the .pdf files back from the API. Now I want to figure out how to send each files on it's own thread instead of all together.
Client:
public async void btnConvert_Click(object sender, EventArgs e)
{
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(BaseApiUrl);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, BaseApiUrl + ApiUrl);
List<string> requests = new List<string>();
byte[] bte;
foreach (string s in docPaths)
{
bte = File.ReadAllBytes(s);
requests.Add(Convert.ToBase64String(bte));
}
var data = JsonConvert.SerializeObject(requests);
request.Content = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response1 = await client.PostAsync(BaseApiUrl + ApiUrl, request.Content);
Task<string> json = response1.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<List<SimpleResponse>>(json.Result);
foreach (SimpleResponse sr in response)
{
if (sr.Success)
{
bte = Convert.FromBase64String(sr.Result.ToString());
string rs = RandomString(16, true);
string pdfFileName = tempPdfPath + rs + ".pdf";
if (File.Exists(pdfFileName))
{
File.Delete(pdfFileName);
}
System.IO.File.WriteAllBytes(pdfFileName, bte);
}
else
{
}
}
}
}
API:
[HttpPost]
public async Task<List<SimpleResponse>> Post([FromBody] List<string> request)
{
List<SimpleResponse> responses = new List<SimpleResponse>();
try
{
Converter convert = new Converter();
foreach (string s in request)
{
var result = convert.CovertDocToPDF(s, WebConfigurationManager.AppSettings["tempDocPath"], WebConfigurationManager.AppSettings["tempPdfPath"]);
responses.Add(new SimpleResponse()
{
Result = result,
Success = true
});
}
}
catch (Exception ex)
{
responses.Add(new SimpleResponse()
{
Result = null,
Success = true,
Exception = ex,
Errors = new List<string>() { string.Format("{0}, {1}", ex.Message, ex.InnerException?.Message ?? "") }
});
}
return responses;
}

TFS SDK Authentication on IIS

We have an ASP.NET WebAPI which generates a custom document using the TFS SDK. We attempted to wrap the entire call stack for the SDK inside a C# impersonation wrapper. Our document is returned corrupted because the TFS client is not authenticating under the IIS Network Service but is correctly returned with data when we set the App Pool identity to a specific user. The EnsureAuthenticated comes back true. The TestManagementService is not null. The ProjectName parameter is not empty and has a valid ProjectName;
[Route("generatetestplan")]
[HttpPost]
public HttpResponseMessage Post([FromBody]TestPlanRequest Request)
{
var wi = (WindowsIdentity)HttpContext.Current.User.Identity;
HttpResponseMessage Res = new HttpResponseMessage(HttpStatusCode.OK);
WindowsIdentity.RunImpersonated(wi.AccessToken, () =>
{
using (var handler = new HttpClientHandler { UseDefaultCredentials = true })
using (var client = new HttpClient(handler))
{
Res = GenerateTestPlan(Request, Res);
}
});
return Res;
}
public HttpResponseMessage GenerateTestPlan(TestPlanRequest Request, HttpResponseMessage Res)
{
var TestResultsGen = new TestResultsGenerator(Request.ProjectName, Request.TestPlanId);
TestResultsGen.Generate();
var Bytes = TestResultsGen.FBytes;
Res.Content = new ByteArrayContent(Bytes);
Res.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return Res;
}
public TestResultsGenerator(string ProjectName, int TestPlanId)
{
TfsTeamProjectCollection = AuthenticateToCollection();
this.TestPlanId = TestPlanId;
this.ProjectName = ProjectName;
try
{
TestManagementService = TfsTeamProjectCollection.GetService<ITestManagementService>();
TeamProject = TestManagementService.GetTeamProject(ProjectName);
}
catch(Exception e)
{
logger.Error(DateTime.Now.ToString() + " Test Service Error: " + e.ToString());
}
}
public static TfsTeamProjectCollection AuthenticateToCollection()
{
var server = ConfigurationManager.AppSettings["TFS"];
TfsTeamProjectCollection TfsCollection = new TfsTeamProjectCollection(new Uri(server), new Microsoft.VisualStudio.Services.Common.VssCredentials());
try
{
TfsCollection.EnsureAuthenticated();
}
catch (Exception e)
{
logger.Error(e.ToString());
AuthenticateToCollection();
}
return Tfs

Incorporating GZIP into Web API

I have a C# application that communicates to my Web API service fine when there is no GZIP being used. When I apply GZIP, my [FromBody] variable is null and I can't seem to pinpoint why this is happening.
If I put a breakpoint in the web api, I can see that data is null when GZIP is applied. When it's not, it is populated.
Any input would be greatly appreciated. If you need any other code examples please let me know
Update Routing Class
public class UpdateRouting
{
public UpdateRouting()
{
Routes = new List<Routing>();
}
public List<Routing> Routes { get; set; }
}
Collect data
private void btnTestRoutingSend_Click(object sender, EventArgs e)
{
try
{
var response = new ResponseObj();
using (var mainContext = new EntityModel())
{
var nodes = mainContext.Nodes.Where(x => x.SystemType == "Dev").ToList();
var updRouting = new UpdateRouting();
foreach (var n in nodes)
{
using (var nodeContext = new EntityModel(connString))
{
var accounts = nodeContext.Accounts;
foreach (var acct in accounts)
{
//code to map accounts to route
}
var customers = nodeContext.Customers;
foreach (var cust in customers)
{
//code to map customer to route
}
}
}
response = webcontext.SendPost<ResponseObj>(updRouting, "Routing", "SyncRouting");
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
SendPost Method
public T SendPost<T>(object update, string controller, string action)
{
var url = _baseURL + String.Format("api/{0}/{1}", controller, action), update);
T retval = default(T);
var uri = new Uri(_baseUri, url);
try
{
var request = GetRequest(uri, method);
if (content != null)
{
var json = GetBodyString(content);
if (!_useCompression)
{
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
var json = GetBodyString(content);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
} else{
using (var gzipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress, false))
{
using (var streamWriter = new StreamWriter(gzipStream))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
}
httpWebRequest.Headers.Add("Content-Encoding", "gzip");
}
}
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
retval = GetObject<T>(result);
}
}
catch (Exception e)
{
_log.Error(string.Format("Error sending {0} request to {1}", method, uri.ToString()), e);
}
return retval;
}
Get Request
protected virtual HttpWebRequest GetRequest(Uri uri, string method)
{
var retval = (HttpWebRequest)WebRequest.Create(uri);
retval.Timeout = 1000 * 60 * 5;
retval.Accept = "application/json";
retval.KeepAlive = true;
retval.ContentType = "application/json";
retval.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
retval.Method = method;
return retval;
}
API Call
[System.Web.Http.HttpPost]
[Route("SyncRouting")]
public ResponseObj SyncRouting([FromBody] UpdateRouting data)
{
var response = new ResponseObj();
try
{
// do stuff
response.Successful = true;
return response;
}
catch (Exception e)
{
response.Successful = false;
response.Errors.Add(new ErrorMsg
{
Message = "Error - " + e.ToString(),
ExceptionMessage = e.Message,
StackTrace = e.StackTrace,
InnerException = e.InnerException.ToString()
});
return response;
}
}

How to compress HttpClient post and receive data in web api

I have the following web api client which sends data to server using json and gzip:
public void Remote_Push(BlockList Blocks)
{
// Pushes pending records to the remote server
using (var Client = new HttpClient())
{
Client.BaseAddress = new Uri(Context.ServerUrl);
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var Content = JsonCompress(Blocks);
var T1 = Client.PostAsync("SyncPush/", Content); T1.Wait();
T1.Result.EnsureSuccess();
}
}
private static ByteArrayContent JsonCompress(object Data)
{
// Compress given data using gzip
var Bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(Data));
using (var Stream = new MemoryStream())
{
using (var Zipper = new GZipStream(Stream, CompressionMode.Compress, true)) Zipper.Write(Bytes, 0, Bytes.Length);
var Content = new ByteArrayContent(Stream.ToArray());
Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
Content.Headers.ContentEncoding.Add("gzip");
return Content;
}
}
On the server, I have created following action in web api controller:
[HttpPost]
public void SyncPush([FromBody]BlockList Blocks)
{
var Context = SyncCreateContext();
var Sync = new Processor(Context);
Sync.ServerPush(Blocks);
}
Previously, I have used PostAsJsonAsync on the client and it worked fine.
Now, I have switched to ByteArrayContent and gzip and no longer works, the Blocks is always null on the server.
What am I missing here, what is wrong or could be the problem?
Here is a sample console application to do what you are trying to do.
/*using System;
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using WebApi.Models;*/
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press any key to POST");
Console.ReadLine();
RemotePush(new BlockList());
Console.ReadLine();
}
public static async void RemotePush(BlockList blocks)
{
try
{
using (var client = new HttpClient())
{
try
{
Console.WriteLine("Please wait.");
client.BaseAddress = new Uri("http://localhost:52521/Home/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = JsonCompress(blocks);
var response = await client.PostAsync("SyncPush/", content);
using (var stream = await response.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
Console.WriteLine(streamReader.ReadToEnd());
}
}
Console.WriteLine("Done.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static MultipartFormDataContent JsonCompress(object data)
{
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
var stream = new MemoryStream();
using (var zipper = new GZipStream(stream, CompressionMode.Compress, true))
{
zipper.Write(bytes, 0, bytes.Length);
}
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(new StreamContent(stream), "gzipContent");
return multipartContent;
}
}
My controller is like this.
[System.Web.Mvc.HttpPost]
public JsonResult SyncPush(BlockList content)
{
try
{
if (content != null)
{
return Json("success", JsonRequestBehavior.AllowGet);
}
return Json("failed due to null", JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("failed " + ex.Message, JsonRequestBehavior.AllowGet);
}
}
just FYI, since .NET Core is not covered and this question is still relevant working .NET Core code. I used brotli, since that is a widely accepted standard today.
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Net.Http.Headers;
using System.IO.Compression;
public static class CompressedJsonHelper
{
private static readonly Lazy<JsonSerializerOptions>
Options = new(() =>
{
var opt = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
//opt.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
return opt;
});
public static HttpContent ToJson(this object data, bool noCompress = false)
{
if (noCompress)
{
ByteArrayContent byteContent = new (ToBytes(data));
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return byteContent;
}
MemoryStream memoryStream = new ();
BrotliStream compress = new (memoryStream, CompressionLevel.Optimal, true);
StreamContent streamContent = new (memoryStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
streamContent.Headers.ContentEncoding.Add("brotli");
JsonSerializer.Serialize(compress, data, Options.Value);
compress.Flush();
memoryStream.Position = 0;
return streamContent;
}
private static byte[] ToBytes(this object data) => JsonSerializer.SerializeToUtf8Bytes(data, Options.Value);
}
and the httpClient code:
HttpRequestMessage request = new(HttpMethod.Post, $"{yourbaseurl}/{path}")
{
Content = json.ToJson()
};
await _httpClient.SendAsync(request, ...) etc

Categories

Resources