ContentLength имеет значение null в рабочей среде, но заполняется в разработке dotnet 8 C#.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 ContentLength имеет значение null в рабочей среде, но заполняется в разработке dotnet 8 C#.

Сообщение Anonymous »

Создано очень простое промежуточное программное обеспечение (с использованием C# dotnet 8) для отслеживания пользователей, конечных точек, к которым они подключаются, размера запроса и размера ответа. Это отлично работает на моей машине, когда я запускаю dotnet run, но когда это загружается на сервер под управлением Windows 2022 с использованием IIS, длина ответа всегда равна NULL.
Вот промежуточное программное обеспечение
///
/// Configure our httpRequest to be buffered so we can read it multiple times ourselves
///
public class UserTrackingMiddleware
{
private readonly RequestDelegate _next;

public UserTrackingMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task Invoke(HttpContext context)
{
// get host from the request and check if it's in the enumeration of allowed hosts
var url = context.Request.GetDisplayUrl();
var querystring = context.Request.QueryString.ToString();
var endpoint = context.GetEndpoint();

if (!string.IsNullOrEmpty(querystring))
{
url = url.Replace(querystring, string.Empty);
querystring = querystring.Substring(1);
}

if (!string.IsNullOrEmpty(url))
{
var scope = context.RequestServices.CreateScope();
var currentUser = scope.ServiceProvider.GetRequiredService();
var user = await currentUser.GetAsync();

if (currentUser.IsAuthenticated)
{
var watch = new Stopwatch();
watch.Start();

var dataContext = scope.ServiceProvider.GetRequiredService();

// userAgent
var userAgent = "unavailable";

if (context.Request.Headers.TryGetValue("User-Agent", out var parsedUserAgent))
userAgent = parsedUserAgent.ToString();

// contentLength
long? requestLength = null;

if (headerKeys.Contains("Content-Length", StringComparer.OrdinalIgnoreCase))
requestLength = long.Parse(context.Request.Headers["Content-Length"].ToString());

// headers
var httpHeaders = new Dictionary();
foreach (var header in headerKeys.OrderBy(e => e))
httpHeaders.Add(header, context.Request.Headers[header]);

var log = new UserTracking
{
UserId = user.Id,
Url = url,
QueryString = querystring,
RequestLength = requestLength,
UserAgent = userAgent,
Method = context.Request.Method.ToLower(),
Headers = JsonConvert.SerializeObject(httpHeaders)
};

dataContext.SetAdded(log);

try
{
await dataContext.SaveChangesAsync(context.RequestAborted);

// To add Headers AFTER everything you need to do this
context.Response.OnStarting(async () =>
{
watch.Stop();

var sqlBuilder = new SqlBuilder("UPDATE UserTracking SET ElapsedMilliseconds = {0}, ResponseLength = {1} WHERE Id = {2}", watch.ElapsedMilliseconds, context.Response.ContentLength, log.Id);
await dataContext.ExecuteSqlCommandAsync(sqlBuilder);
});
}
catch (Exception)
{
// an error occurred here
}
}
}

await _next(context);
}
}
}


На моем локальном компьютере результаты SQL выглядят так
Изображение

Но на сервере вы можете видеть, что параметр responseLength равен NULL
[img]https://i.sstatic. net/Kn99ldAG.png[/img]

Мои локальные настройки запуска выглядят так
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}

Я читал, что ContentLength ответа имеет значение NULL, потому что ответ не буферизуется, и вам нужно поместить его в поток памяти, чтобы получить длину ответа, но почему это работает при разработке, но не на сервере?
Промежуточное ПО добавляется через Program.cs, как показано ниже.

// must be done before all other middleware, expect developer exception page
app.UseHsts(options =>
{
options.MaxAge(120, 0, 1, 0);
options.AllResponses();
options.IncludeSubdomains();
});

// middleware
app.UseGlobalExceptionHandler();
app.UseOperationCancelledExceptionHandler();
app.UseResponseCaching();
app.UseResponseCompression();

// Content Security Policy (CSP)
app.UseSecurityPolicy();
app.UseCsp(options =>
{
...
});

// swagger
app.UseStaticFiles(new StaticFileOptions()
{
...
});

// app
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "app")),

// accessing wwwroot inside folder contents
RequestPath = new PathString(""),

// add cache headers
OnPrepareResponse = (context) =>
{
var headers = context.Context.Response.GetTypedHeaders();
headers.CacheControl = new CacheControlHeaderValue()
{
Public = false,
Private = true,
MaxAge = TimeSpan.FromHours(24)
};

// these are also in the securityPolicyMiddleware
headers.Set("Permissions-Policy", "accelerometer=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()");
headers.Set("Referrer-Policy", "strict-origin-when-cross-origin");
headers.Set("X-Content-Type-Options", "nosniff");
headers.Set("X-Frame-Options", "DENY");
headers.Set("X-Permitted-Cross-Domain-Policies", "none");
}
});

// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger(options =>
{
...
});

// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(options =>
{
...
});

// routing
app.UseRouting();

// CORS - Configuring is with MvcExtensions
app.UseCors();

// comment this out and you get an error saying
// InvalidOperationException: No authentication handler is configured to handle the scheme: Microsoft.AspNet.Identity.External
app.UseAuthentication();

// for authorization headers
app.UseAuthorization();

// antiforgery
app.UseAntiforgery();

// user tracking

Подробнее здесь: https://stackoverflow.com/questions/791 ... et-8-c-sha
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»