-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.NET 8 has introduced stream operation for JsonSerializer of System.Text.Json, utilized this. #150
Comments
check if https://learn.microsoft.com/en-us/dotnet/api/system.net.http.json.httpclientjsonextensions utilize the stream operation. |
public async Task<DemoWebApi.DemoData.Client.Company> CreateCompanyAsync(DemoWebApi.DemoData.Client.Company p, Action<System.Net.Http.Headers.HttpRequestHeaders> handleHeaders = null)
{
var requestUri = "api/Entities/createCompany";
// using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri);
//var contentJson = JsonSerializer.Serialize(p, jsonSerializerSettings);
//var content = new StringContent(contentJson, System.Text.Encoding.UTF8, "application/json");
//httpRequestMessage.Content = content;
//handleHeaders?.Invoke(httpRequestMessage.Headers);
var responseMessage = await client.PostAsJsonAsync<DemoWebApi.DemoData.Client.Company>(requestUri, p, jsonSerializerSettings);
try
{
responseMessage.EnsureSuccessStatusCodeEx();
if (responseMessage.StatusCode == System.Net.HttpStatusCode.NoContent) { return null; }
var contentString = await responseMessage.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<DemoWebApi.DemoData.Client.Company>(contentString, jsonSerializerSettings);
}
finally
{
responseMessage.Dispose();
}
}
/// <summary>
/// POST api/Entities/createCompany
/// </summary>
public DemoWebApi.DemoData.Client.Company CreateCompany(DemoWebApi.DemoData.Client.Company p, Action<System.Net.Http.Headers.HttpRequestHeaders> handleHeaders = null)
{
var requestUri = "api/Entities/createCompany";
//using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri);
//var contentJson = JsonSerializer.Serialize(p, jsonSerializerSettings);
//var content = new StringContent(contentJson, System.Text.Encoding.UTF8, "application/json");
//httpRequestMessage.Content = content;
//handleHeaders?.Invoke(httpRequestMessage.Headers);
var responseMessage = client.PostAsJsonAsync<DemoWebApi.DemoData.Client.Company>(requestUri, p, jsonSerializerSettings).Result;
try
{
responseMessage.EnsureSuccessStatusCodeEx();
if (responseMessage.StatusCode == System.Net.HttpStatusCode.NoContent) { return null; }
var contentString = responseMessage.Content.ReadAsStringAsync().Result;
return JsonSerializer.Deserialize<DemoWebApi.DemoData.Client.Company>(contentString, jsonSerializerSettings);
}
finally
{
responseMessage.Dispose();
}
} |
Basically done, however, I found out that I have supported custom request headers manipulation, and the extensions do not support. So now I have to reverse the change, since custom header manipulation is important for many real world applications., then just keep a copy here: void RenderPostOrPutImplementation(string httpMethod)
{
//Create function parameters in prototype
CodeParameterDeclarationExpression[] parameters = description.ParameterDescriptions.Where(p => p.ParameterDescriptor.ParameterBinder == ParameterBinder.FromUri
|| p.ParameterDescriptor.ParameterBinder == ParameterBinder.FromQuery || p.ParameterDescriptor.ParameterBinder == ParameterBinder.FromBody
|| p.ParameterDescriptor.ParameterBinder == ParameterBinder.None).Select(d =>
{
AddCustomPocoTypeForCs(d.ParameterDescriptor.ParameterType);
CodeParameterDeclarationExpression exp = new CodeParameterDeclarationExpression(poco2CsGen.TranslateToClientTypeReference(d.ParameterDescriptor.ParameterType), d.Name);
exp.UserData.Add(Fonlow.TypeScriptCodeDom.UserDataKeys.ParameterDescriptor, d.ParameterDescriptor);
return exp;
}
).ToArray();
clientMethod.Parameters.AddRange(parameters);
if (codeGenOutputsSettings.CancellationTokenEnabled)
{
clientMethod.Parameters.Add(new CodeParameterDeclarationExpression("System.Threading.CancellationToken", "cancellationToken"));
}
if (codeGenOutputsSettings.HandleHttpRequestHeaders)
{
clientMethod.Parameters.Add(new CodeParameterDeclarationExpression("Action<System.Net.Http.Headers.HttpRequestHeaders>", "handleHeaders = null"));
}
ParameterDescription[] fromBodyParameterDescriptions = description.ParameterDescriptions.Where(d => d.ParameterDescriptor.ParameterBinder == ParameterBinder.FromBody
|| (TypeHelper.IsComplexType(d.ParameterDescriptor.ParameterType) && (!(d.ParameterDescriptor.ParameterBinder == ParameterBinder.FromUri) || (d.ParameterDescriptor.ParameterBinder == ParameterBinder.None)))).ToArray();
if (fromBodyParameterDescriptions.Length > 1)
{
throw new CodeGenException("Bad Api Definition")
{
Description = String.Format("This API function {0} has more than 1 FromBody bindings in parameters", description.ActionDescriptor.ActionName)
};
}
ParameterDescription singleFromBodyParameterDescription = fromBodyParameterDescriptions.FirstOrDefault();
void AddRequestUriWithQueryAssignmentStatement()
{
string jsUriQuery = UriQueryHelper.CreateUriQuery(description.RelativePath, description.ParameterDescriptions);
string uriText = jsUriQuery == null ? $"\"{description.RelativePath}\"" : RemoveTrialEmptyString($"\"{jsUriQuery}\"");
clientMethod.Statements.Add(new CodeVariableDeclarationStatement(
new CodeTypeReference("var"), "requestUri",
new CodeSnippetExpression(uriText)));
}
AddRequestUriWithQueryAssignmentStatement();
bool hasBody = singleFromBodyParameterDescription != null;
if (!codeGenOutputsSettings.UseSystemTextJson // use Newtonsoft.Json
|| (codeGenOutputsSettings.UseSystemTextJson && codeGenOutputsSettings.UseHttpClientJsonExtensions && !hasBody))
{
clientMethod.Statements.Add(new CodeSnippetStatement(
ThreeTabs + $"using var httpRequestMessage = new HttpRequestMessage(HttpMethod.{httpMethod}, requestUri);"));
}
if (hasBody)
{
if (codeGenOutputsSettings.UseSystemTextJson)
{
if (!codeGenOutputsSettings.UseHttpClientJsonExtensions)
{
clientMethod.Statements.Add(new CodeSnippetStatement(ThreeTabs + $"var contentJson = JsonSerializer.Serialize({singleFromBodyParameterDescription.ParameterDescriptor.ParameterName}, jsonSerializerSettings);"));
clientMethod.Statements.Add(new CodeSnippetStatement(ThreeTabs + @"var content = new StringContent(contentJson, System.Text.Encoding.UTF8, ""application/json"");"));
}
}
else
{
clientMethod.Statements.Add(new CodeSnippetStatement(
$"\t\t\tusing var requestWriter = new System.IO.StringWriter();{Environment.NewLine}\t\t\tvar requestSerializer = JsonSerializer.Create(jsonSerializerSettings);"
));
clientMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeSnippetExpression("requestSerializer"), "Serialize",
new CodeSnippetExpression("requestWriter"),
new CodeSnippetExpression(singleFromBodyParameterDescription.ParameterDescriptor.ParameterName)));
clientMethod.Statements.Add(new CodeSnippetStatement(
@" var content = new StringContent(requestWriter.ToString(), System.Text.Encoding.UTF8, ""application/json"");"
));
}
if (!codeGenOutputsSettings.UseHttpClientJsonExtensions)
{
clientMethod.Statements.Add(new CodeSnippetStatement("\t\t\thttpRequestMessage.Content = content;"));
if (codeGenOutputsSettings.HandleHttpRequestHeaders)
{
clientMethod.Statements.Add(new CodeSnippetStatement("\t\t\thandleHeaders?.Invoke(httpRequestMessage.Headers);"));
}
}
}
if (codeGenOutputsSettings.UseHttpClientJsonExtensions && hasBody)
{
AddResponseMessageJsonPostPutAsync(clientMethod, httpMethod, singleFromBodyParameterDescription.ParameterDescriptor.ParameterName);
}
else
{
AddResponseMessageSendAsync(clientMethod); //output: client.SendAsync(httpRequestMessage)
}
CodeVariableReferenceExpression resultReference = new CodeVariableReferenceExpression("responseMessage");
if (returnTypeIsStream)
{
clientMethod.Statements.Add(new CodeMethodInvokeExpression(resultReference, statementOfEnsureSuccessStatusCode));
//Statement: return something;
if (returnType != null)
{
AddReturnStatement(clientMethod.Statements);
}
}
else
{
CodeTryCatchFinallyStatement try1 = new CodeTryCatchFinallyStatement();
clientMethod.Statements.Add(try1);
try1.TryStatements.Add(new CodeMethodInvokeExpression(resultReference, statementOfEnsureSuccessStatusCode));
//Statement: return something;
if (returnType != null)
{
AddReturnStatement(try1.TryStatements);
}
try1.FinallyStatements.Add(new CodeMethodInvokeExpression(resultReference, "Dispose"));
}
if (singleFromBodyParameterDescription != null && !codeGenOutputsSettings.UseSystemTextJson)
{
//Add3TEndBacket(clientMethod);
}
}
static string ThreeTabs => "\t\t\t";
void AddResponseMessageSendAsync(CodeMemberMethod method)
{
string cancellationToken = codeGenOutputsSettings.CancellationTokenEnabled ? ", cancellationToken" : String.Empty;
method.Statements.Add(new CodeVariableDeclarationStatement(
new CodeTypeReference("var"), "responseMessage", forAsync ? new CodeSnippetExpression($"await client.SendAsync(httpRequestMessage{cancellationToken})") : new CodeSnippetExpression($"client.SendAsync(httpRequestMessage{cancellationToken}).Result")));
}
void AddResponseMessageJsonPostPutAsync(CodeMemberMethod method, string httpMethod, string bodyParamName)
{
string cancellationToken = codeGenOutputsSettings.CancellationTokenEnabled ? ", cancellationToken" : String.Empty;
method.Statements.Add(new CodeVariableDeclarationStatement(
new CodeTypeReference("var"), "responseMessage", forAsync ?
new CodeSnippetExpression($"await client.{httpMethod}AsJsonAsync(requestUri, {bodyParamName}, jsonSerializerSettings{cancellationToken});")
: new CodeSnippetExpression($"client.{httpMethod}AsJsonAsync(requestUri, {bodyParamName}, jsonSerializerSettings{cancellationToken}).Result")));
} |
use this instead: var content = System.Net.Http.Json.JsonContent.Create(p, mediaType: null, jsonSerializerSettings); |
done |
.NET 6 had introduced Utf8JsonReader in .NET 6, and stream in .NET 8.
The text was updated successfully, but these errors were encountered: