Closed zijianhuang closed 5 months ago
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.