RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-547996

air's questions

Martin Hope
air
Asked: 2024-11-25 04:49:54 +0000 UTC

使用线程安全字典时的数据竞争

  • 5

问题很简单:为什么线程安全字典允许数据竞争,因为该字典中的所有方法都是原子的,并且两个线程不应该接收相同的值?

在下面的示例中,可以显示至少10个、至少12个、至少14个。

public class Program
{
    private static ConcurrentDictionary<string, int> _map = [];

    static async Task Main(string[] args)
    {
        _map["air"] = 0;
        var tasks = new List<Task>();

        for (int i = 0; i < 10000; i++)
        {
            tasks.Add(Task.Run(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    _map.TryGetValue("air", out int value);
                    _map.AddOrUpdate("air", value, (key, oldValue) => oldValue + 1);

                    _map.TryGetValue("air", out int newValue);
                    if (newValue >= 10)
                    {
                        _map.TryRemove("air", out _);
                        _map.TryAdd("air1", newValue);
                    }
                }
            }));
        }

        await Task.WhenAll(tasks);
        Console.WriteLine(_map["air1"]);
    }
}
c#
  • 1 个回答
  • 82 Views
Martin Hope
air2921
Asked: 2024-04-22 22:04:15 +0000 UTC

将字符串拆分为子字符串,同时保留分隔符

  • 5

任务本身很简单,将其分割,然后在分割后的子串上添加分隔符号。

但不是。

需要对一个大字符串进行分割,即在保留子字符串中分隔符的同时,不能创建新的字符串!

我尝试使用string.split和Regex.Split进行分割,但结果是相同的,分隔符被删除。

我尝试了这些选项:

var str = "hello=world=";

foreach (var subStr in str.Split('='))
    Console.WriteLine(subStr);

foreach (var subStr in Regex.Split(str, "="))
    Console.WriteLine(subStr);

foreach (var subStr in Regex.Split(str, @"(\=)"))
    Console.WriteLine(subStr);

但它们都不合适,它们的控制台输出是:

hello
world

hello
world

hello
=
world
=

结果是我所期望的:

hello=
world=
c#
  • 1 个回答
  • 39 Views
Martin Hope
air2921
Asked: 2024-03-16 05:13:17 +0000 UTC

在 Docker 中运行应用程序时创建迁移

  • 5

在 Docker 中运行容器时如何创建迁移和数据库架构?

我编写了以下 docker-compose 文件,一切都开始顺利,但是当我尝试访问数据库并在那里搜索实体时,表不在那里。如何在启动容器时创建它们(如果它们不存在)?

别用石头打我,我只是第一天掌握 docker

version: '3.4'

networks:
  webapi:
    driver: bridge

services:
  webapi:
    container_name: webapi-dev
    image: ${DOCKER_REGISTRY-}webapi
    build:
      context: .
      dockerfile: webapi/Dockerfile
    ports:
      - "8080:8080"
    networks:
      - "webapi"
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    depends_on:
      - postgres_db
      - redis
      - clamav

  postgres_db:
    container_name: postgres
    image: postgres:latest
    ports:
      - "5432:5432"
    networks:
      - "webapi"
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 123
      POSTGRES_DB: filecryptweb
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    container_name: redis
    image: redis:latest
    ports:
      - "6379:6379"
    networks:
      - "webapi"

  clamav:
    container_name: clamav
    image: mkodockx/docker-clamav:alpine
    environment:
      CLAMD_CONF_MaxFileSize: 250M
      CLAMD_CONF_MaxScanSize: 250M
      CLAMD_CONF_StreamMaxLength: 250M
    restart: always
    ports:
      - "3310:3310"
    networks:
      - "webapi"

volumes:
  postgres-data:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["webapi/webapi.csproj", "webapi/"]
RUN dotnet restore "./webapi/webapi.csproj"
COPY . .
WORKDIR "/src/webapi"
RUN dotnet build "./webapi.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./webapi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "webapi.dll"]

2024-03-16 04:10:54 webapi-dev  | [21:10:54 INF] { username = , id = , role =  } { path = /api/auth/login, method = POST }
2024-03-16 04:10:54 webapi-dev  | [21:10:54 INF] Executing endpoint 'webapi.Controllers.Account.AuthSessionController.Login (webapi)'
2024-03-16 04:10:54 webapi-dev  | [21:10:54 INF] Route matched with {action = "Login", controller = "AuthSession"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] Login(webapi.DTO.AuthDTO) on controller webapi.Controllers.Account.AuthSessionController (webapi).
2024-03-16 04:10:55 postgres    | 2024-03-15 21:10:55.845 UTC [33] ERROR:  relation "users" does not exist at character 91
2024-03-16 04:10:55 postgres    | 2024-03-15 21:10:55.845 UTC [33] STATEMENT:  SELECT u.id, u.email, u.is_2fa_enabled, u.is_blocked, u.password, u.role, u.username
2024-03-16 04:10:55 postgres    |       FROM users AS u
2024-03-16 04:10:55 postgres    |       WHERE u.email = $1
2024-03-16 04:10:55 postgres    |       LIMIT 1
2024-03-16 04:10:55 webapi-dev  | [21:10:55 ERR] Failed executing DbCommand (99ms) [Parameters=[@__ToLowerInvariant_0='?'], CommandType='Text', CommandTimeout='30']
2024-03-16 04:10:55 webapi-dev  | SELECT u.id, u.email, u.is_2fa_enabled, u.is_blocked, u.password, u.role, u.username
2024-03-16 04:10:55 webapi-dev  | FROM users AS u
2024-03-16 04:10:55 webapi-dev  | WHERE u.email = @__ToLowerInvariant_0
2024-03-16 04:10:55 webapi-dev  | LIMIT 1
2024-03-16 04:10:55 webapi-dev  | [21:10:55 ERR] An exception occurred while iterating over the results of a query for context type 'webapi.DB.FileCryptDbContext'.
2024-03-16 04:10:55 webapi-dev  | Npgsql.PostgresException (0x80004005): 42P01: relation "users" does not exist
2024-03-16 04:10:55 webapi-dev  | 
2024-03-16 04:10:55 webapi-dev  | POSITION: 91
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
2024-03-16 04:10:55 webapi-dev  |    at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
2024-03-16 04:10:55 webapi-dev  |   Exception data:
2024-03-16 04:10:55 webapi-dev  |     Severity: ERROR
2024-03-16 04:10:55 webapi-dev  |     SqlState: 42P01
2024-03-16 04:10:55 webapi-dev  |     MessageText: relation "users" does not exist
2024-03-16 04:10:55 webapi-dev  |     Position: 91
2024-03-16 04:10:55 webapi-dev  |     File: parse_relation.c
2024-03-16 04:10:55 webapi-dev  |     Line: 1449
2024-03-16 04:10:55 webapi-dev  |     Routine: parserOpenTable
2024-03-16 04:10:55 webapi-dev  | Npgsql.PostgresException (0x80004005): 42P01: relation "users" does not exist
2024-03-16 04:10:55 webapi-dev  | 
2024-03-16 04:10:55 webapi-dev  | POSITION: 91
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
2024-03-16 04:10:55 webapi-dev  |    at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
2024-03-16 04:10:55 webapi-dev  |   Exception data:
2024-03-16 04:10:55 webapi-dev  |     Severity: ERROR
2024-03-16 04:10:55 webapi-dev  |     SqlState: 42P01
2024-03-16 04:10:55 webapi-dev  |     MessageText: relation "users" does not exist
2024-03-16 04:10:55 webapi-dev  |     Position: 91
2024-03-16 04:10:55 webapi-dev  |     File: parse_relation.c
2024-03-16 04:10:55 webapi-dev  |     Line: 1449
2024-03-16 04:10:55 webapi-dev  |     Routine: parserOpenTable
2024-03-16 04:10:55 webapi-dev  | [21:10:55 FTL] Npgsql.PostgresException (0x80004005): 42P01: relation "users" does not exist
2024-03-16 04:10:55 webapi-dev  | 
2024-03-16 04:10:55 webapi-dev  | POSITION: 91
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
2024-03-16 04:10:55 webapi-dev  |    at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
2024-03-16 04:10:55 webapi-dev  |    at webapi.DB.Repository`1.GetByFilter(Func`2 queryModifier, CancellationToken cancellationToken) in C:\Users\Stewi\Source\Repos\air2921\FileCryptWeb\webapi\DB\Repository.cs:line 77
2024-03-16 04:10:55 webapi-dev  |   Exception data:
2024-03-16 04:10:55 webapi-dev  |     Severity: ERROR
2024-03-16 04:10:55 webapi-dev  |     SqlState: 42P01
2024-03-16 04:10:55 webapi-dev  |     MessageText: relation "users" does not exist
2024-03-16 04:10:55 webapi-dev  |     Position: 91
2024-03-16 04:10:55 webapi-dev  |     File: parse_relation.c
2024-03-16 04:10:55 webapi-dev  |     Line: 1449
2024-03-16 04:10:55 webapi-dev  |     Routine: parserOpenTable
2024-03-16 04:10:56 webapi-dev  | [21:10:56 INF] Executing ObjectResult, writing value of type '<>f__AnonymousType0`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'.
2024-03-16 04:10:56 webapi-dev  | [21:10:56 INF] Executed action webapi.Controllers.Account.AuthSessionController.Login (webapi) in 1115.6806ms
2024-03-16 04:10:56 webapi-dev  | [21:10:56 INF] Executed endpoint 'webapi.Controllers.Account.AuthSessionController.Login (webapi)'
2024-03-16 04:10:56 webapi-dev  | [21:10:56 INF] Status Code: 500
2024-03-16 04:10:56 webapi-dev  | [21:10:56 INF] Request finished HTTP/2 POST https://localhost:8081/api/auth/login - 500 null application/json; charset=utf-8 1280.3549ms
postgresql
  • 2 个回答
  • 35 Views
Martin Hope
air2921
Asked: 2024-01-22 08:01:44 +0000 UTC

页面未扩展到全屏

  • 5

我开始尝试在 React 中设置页面样式,遇到了一个问题:页面组件被压到屏幕左边缘,而其余空间没有填充样式。

这是我们得到的图片:

在此输入图像描述

我不明白问题出在哪里,是在样式中,还是在 React 本身中

这是组件类本身:

export default class NotFound extends Component {
    static NotFoundComponent() {
        return (
            <div className="error-container">
                <div className="error-code">
                    <h1>404</h1>
                </div>
                <br />
                <div className="error-description">
                    <h2>Page not found</h2>
                </div>
                <div className="divider"></div>
                <Link to="/" className="main-button">
                    Back to main page
                </Link>
            </div>
        );
    }

    render() {
        return (
            <>
                {NotFound.NotFoundComponent()}
            </>
        );
    }
}

这是 NotFound.css 样式文件:

.error-container {
    background-color: black;
    color: white;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    min-height: 100vh;
    padding-top: 100px;
}

.error-code h1 {
    font-size: 5em;
}

.main-button {
    display: inline-block;
    padding: 15px 30px;
    font-size: 1.2em;
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
    text-decoration: none;
    margin: 0 auto;
}

.error-description h2 {
    font-size: 2em;
    color: gray;
    flex: 1;
}

.divider {
    width: 80px;
    height: 2px;
    background-color: gray;
    margin-top: 20px;
    margin-bottom: 20px;
}

这是index.css 文件:

:root {
  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  font-weight: 500;
  color: #646cff;
  text-decoration: inherit;
}
a:hover {
  color: #535bf2;
}

body {
  margin: 0;
  display: flex;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}
html
  • 1 个回答
  • 44 Views
Martin Hope
air2921
Asked: 2024-01-10 05:23:23 +0000 UTC

会话数据的泄露和修改

  • 5

出现了关于客户端的会话数据是否会被泄露或更改的问题。

假设我将用户数据保存在会话中

HttpContext.Session.SetString(ROLE, "User")

当从会话接收这些数据时,我不想获得不是User 的角色,但假设是Admin

因为在我的例子中,会话中的数据用于创建 jwt。

因此,据我了解,用户不会接收数据本身,他只接收会话标识符,并且假设数据不会被泄露或更改是合乎逻辑的,因为数据本身存储在服务器上,并且用户只有标识符,并不直接与该数据交互。

但我对此不确定,也许有一些值得担心的漏洞,如果有的话,请告诉我们。

如果有任何信息,我将非常感激。

我的情况,为什么我认为我需要会议:

主要端点验证数据并通常执行一些逻辑:

    [HttpPost("login")]
    public async Task<IActionResult> Login(UserModel userModel)
    {
        try
        {
            if (userModel.email is null || userModel.password is null)
                return StatusCode(422, new { message = AccountErrorMessage.InvalidUserData });

            var email = userModel.email.ToLowerInvariant();
            var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.email == email);
            if (user is null)
                return StatusCode(404, new { message = AccountErrorMessage.UserNotFound });

            bool IsCorrect = _passwordManager.CheckPassword(userModel.password, user.password!);
            if (!IsCorrect)
                return StatusCode(401, new { message = AccountErrorMessage.PasswordIncorrect });

            var clientInfo = Parser.GetDefault().Parse(HttpContext.Request.Headers["User-Agent"].ToString());

            if ((bool)!user.is_2fa_enabled)
                return await FactLogin(clientInfo, user);

            int code = _generateCode.GenerateSixDigitCode();
            var emailDto = new EmailDto
            {
                username = user.username,
                email = user.email,
                subject = EmailMessage.Verify2FaHeader,
                message = EmailMessage.Verify2FaBody + code
            };

            await _emailSender.SendMessage(emailDto);

            HttpContext.Session.SetString(ID, user.id.ToString());
            HttpContext.Session.SetString(EMAIL, email);
            HttpContext.Session.SetString(USERNAME, user.username!);
            HttpContext.Session.SetString(ROLE, user.role!);
            HttpContext.Session.SetString(CODE, code.ToString());

            return StatusCode(200, new { message = AccountSuccessMessage.EmailSended });
        }
        catch (UserException)
        {
            _logger.LogCritical("When trying to update the data, the user was deleted");
            _tokenService.DeleteTokens();
            _logger.LogDebug("Tokens was deleted");
            return StatusCode(404);
        }
        catch (Exception)
        {
            return StatusCode(500);
        }
    }

验证端点:

    [HttpPost("verify/2fa")]
    public async Task<IActionResult> VerifyTwoFA([FromQuery] int code)
    {
        int correctCode = int.Parse(HttpContext.Session.GetString(CODE));
        int userId = int.Parse(HttpContext.Session.GetString(ID));
        string? email = HttpContext.Session.GetString(EMAIL);
        string? username = HttpContext.Session.GetString(USERNAME);
        string? role = HttpContext.Session.GetString(ROLE);

        if (email is null || username is null || role is null)
            return StatusCode(422, new { message = AccountErrorMessage.NullUserData });

        if (!code.Equals(correctCode))
            return StatusCode(422, new { message = AccountErrorMessage.CodeIncorrect });

        var clientInfo = Parser.GetDefault().Parse(HttpContext.Request.Headers["User-Agent"].ToString());
        var userModel = new UserModel
        {
            id = userId,
            username = username,
            email = email,
            role = role
        };

        HttpContext.Session.Clear();
        return await FactLogin(clientInfo, userModel);
    }

是的,当然,你可以再次向数据库请求数据,但我不想再次加载数据库

c#
  • 1 个回答
  • 51 Views
Martin Hope
air2921
Asked: 2023-11-21 20:15:18 +0000 UTC

通过 JOIN 访问第二个表的属性时为 null 值

  • 5

当尝试发出 JOIN 请求时,Tokens 属性结果为 null:

                var user = await dbContext.Tokens
                    .Where(t => t.refresh_token == hashRefreshToken)
                    .Join(dbContext.Users, token => token.user_id, user => user.id, (token, user) => user)
                    .FirstOrDefaultAsync();

虽然如果您发出 2 个单独的请求,则 token 中不会有空值:

var token = await dbContext.Tokens.FirstOrDefaultAsync(t => t.refresh_token == hashRefreshToken);

var user = await dbContext.Users.FindAsync(token.user_id);

这是代币模型:

[Table("tokens")]
public class TokenModel
{
    [Key]
    public int token_id { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? refresh_token { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public DateTime? expiry_date { get; set; }

    [ForeignKey("user_id")]
    public int user_id { get; set; }

    [JsonIgnore]
    public UserModel User { get; set; }
}

用户模型:

[Table("users")]
public class UserModel
{
    [Key]
    [Required]
    public int id { get; set; }

    [Required]
    public string username { get; set; }

    [Required]
    public string role { get; set; }

    [EmailAddress]
    [Required]
    public string email { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string password_hash { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? api_key { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public UserQuotasModel Quotas { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public UserKeyModel Keys { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public ICollection<UserFileModel> Files { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public TokenModel Tokens { get; set; }

    //[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    //public ApiModel API { get; set; }
}

这是 modelBuilder 中关系的配置方式:

        modelBuilder.Entity<UserModel>()
            .HasOne(u => u.Tokens)
            .WithOne(t => t.User)
            .HasForeignKey<TokenModel>(t => t.user_id)
            .OnDelete(DeleteBehavior.Cascade);

那么数据库集:

public DbSet<TokenModel> Tokens { get; set; }

这是一个使用 Join 和 token 属性 == null 的中间件选项

    public async Task Invoke(HttpContext context, FileCryptDbContext dbContext, ITokenService tokenService)
    {
        if(context.Request.Cookies.TryGetValue("JwtToken", out string? JwtToken))
        {
            context.Request.Headers.Add("Authorization", $"Bearer {JwtToken}");
        }
        else
        {
            if(context.Request.Cookies.TryGetValue("RefreshToken", out string? RefreshToken))
            {
                var hashRefreshToken = tokenService.HashingToken(RefreshToken);
                //var token = await dbContext.Tokens.FirstOrDefaultAsync(t => t.refresh_token == hashRefreshToken);

                var user = await dbContext.Tokens
                    .Where(t => t.refresh_token == hashRefreshToken)
                    .Join(dbContext.Users, token => token.user_id, user => user.id, (token, user) => user)
                    .FirstOrDefaultAsync();

                if (user is not null && user.Tokens.expiry_date.HasValue)
                {
                    if (user.Tokens.expiry_date > DateTime.UtcNow)
                    {
                        //var user = await dbContext.Users.FindAsync(token.user_id);
                        var userModel = new UserModel { id = user.id, username = user.username, email = user.email, role = user.role };
                        string NewJwtToken = tokenService.GenerateJwtToken(userModel, 20);
                        var JwtCookieOptions = tokenService.SetCookieOptions(TimeSpan.FromMinutes(20));
                        context.Response.Cookies.Append("JwtToken", NewJwtToken, JwtCookieOptions);

                        context.Request.Headers.Add("Authorization", $"Bearer {NewJwtToken}");
                    }
                }
            }
        }
        await _next(context);
    }

好吧,这里有一个选项,其中使用了 2 个单独的请求,并且一切正常:

    public async Task Invoke(HttpContext context, FileCryptDbContext dbContext, ITokenService tokenService)
    {
        if(context.Request.Cookies.TryGetValue("JwtToken", out string? JwtToken))
        {
            context.Request.Headers.Add("Authorization", $"Bearer {JwtToken}");
        }
        else
        {
            if(context.Request.Cookies.TryGetValue("RefreshToken", out string? RefreshToken))
            {
                var hashRefreshToken = tokenService.HashingToken(RefreshToken);
                var token = await dbContext.Tokens.FirstOrDefaultAsync(t => t.refresh_token == hashRefreshToken);

                if (token is not null && token.expiry_date.HasValue)
                {
                    if (token.expiry_date > DateTime.UtcNow)
                    {
                        var user = await dbContext.Users.FindAsync(token.user_id);

                        var userModel = new UserModel { id = user.id, username = user.username, email = user.email, role = user.role };
                        string NewJwtToken = tokenService.GenerateJwtToken(userModel, 20);
                        var JwtCookieOptions = tokenService.SetCookieOptions(TimeSpan.FromMinutes(20));
                        context.Response.Cookies.Append("JwtToken", NewJwtToken, JwtCookieOptions);

                        context.Request.Headers.Add("Authorization", $"Bearer {NewJwtToken}");
                    }
                }
            }
        }
        await _next(context);
    }

我注意到,如果您使用 Include,那么一切正常:

                var user = await dbContext.Tokens
                    .Where(t => t.refresh_token == hashRefreshToken)
                    .Include(t => t.User)
                    .FirstOrDefaultAsync();
c#
  • 2 个回答
  • 48 Views
Martin Hope
air
Asked: 2023-10-20 23:41:01 +0000 UTC

关闭文件连接

  • 5

我无法弄清楚我在哪里错误地释放了资源/关闭了文件。我在任何地方都使用 using,但仍然出现该文件已被另一个进程使用的异常

public class DownloadControllerBase : ControllerBase
{
    private readonly IUpdateFile _updateFile;
    public DownloadControllerBase(IUpdateFile updateFile)
    {
        _updateFile = updateFile;
    }

    public async Task<IActionResult> DownloadFilesBase(
        int userID,
        string folderForDownloadCryptedFiles,
        string zipFileName)
    {
        try
        {
            string encryptedFilesFolder = Path.Combine(folderForDownloadCryptedFiles, $"User({userID})");
            string[] files = Directory.GetFiles(encryptedFilesFolder);

            if (files.Length == 0)
                return StatusCode(404, new { message = BaseErrorMessage.DownloadNoFiles });

            string zipFilePath = Path.Combine(encryptedFilesFolder, zipFileName);
            await CreateZipFile(userID, zipFilePath, files);

            return await DeleteZipAndCreateResponse(zipFilePath, zipFileName);
        }
        catch (DirectoryNotFoundException)
        {
            return StatusCode(404, new { message = BaseErrorMessage.FolderNotFound });
        }
    }

    private async Task CreateZipFile(int userID, string zipFilePath, string[] files)
    {
        using var zipStream = new FileStream(zipFilePath, FileMode.Create);
        using var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true);
        foreach (var file in files)
        {
            var fileInfo = new FileInfo(file);
            var entry = archive.CreateEntry(fileInfo.Name, CompressionLevel.Fastest);

            using (var entryStream = entry.Open())
            using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
            {
                await fileStream.CopyToAsync(entryStream);
            }
            var fileName = Path.GetFileName(file);
            await UpdateFile(userID, fileName);

            await Task.Run(() => System.IO.File.Delete(file));
        }
    }

    private async Task UpdateFile(int userID, string fileName)
    {
        var DbData = new UserFileModel()
        {
            user_id = userID,
            file_name = fileName,
            status = Status.downloaded.ToString(),
            download_time = DateTime.UtcNow
        };

        await _updateFile.UpdateFileByNameOrID(DbData, "fileName");
    }

    private async Task<IActionResult> DeleteZipAndCreateResponse(string zipFilePath, string zipFileName)
    {
        using var stream = new FileStream(zipFilePath, FileMode.Open, FileAccess.Read);

        await Task.Run(() => System.IO.File.Delete(zipFilePath));

        return File(stream, "application/zip", zipFileName);
    }
}

这是在控制器中调用该方法的方式:

    [HttpGet("Download")]
    public async Task<IActionResult> DownloadFiles([FromRoute] string type)
    {
        try
        {
            var param = _cryptographyParams.GetCryptographyParamsNoKey(type, FuncType.encrypt.ToString());

            return await _downloadController.DownloadFilesBase(_userInfo.UserId, param.downloadFolder, "EncryptedFiles.zip");
        }
        catch (InvalidRouteException ex)
        {
            return StatusCode(404, new { message = ex.Message });
        }
    }

异常日志:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.IO.IOException: The process cannot access the file 'C:\FileCryptWeb Users\Private\Encrypted files for download\User(22)\EncryptedFiles.zip' because it is being used by another process.
         at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
         at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
         at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
         at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
         at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
         at FileCryptWeb.Controllers.BaseControllers.DownloadControllerBase.CreateZipFile(Int32 userID, String zipFilePath, String[] files) in C:\Users\Stewi\Source\Repos\air2921\FileCryptWeb\FileCryptWeb\Controllers\BaseControllers\DownloadControllerBase.cs:line 51
         at FileCryptWeb.Controllers.BaseControllers.DownloadControllerBase.DownloadFilesBase(Int32 userID, String folderForDownloadCryptedFiles, String zipFileName) in C:\Users\Stewi\Source\Repos\air2921\FileCryptWeb\FileCryptWeb\Controllers\BaseControllers\DownloadControllerBase.cs:line 31
         at FileCryptWeb.Controllers.CryptionControllers.EncryptionController.DownloadFiles(String type) in C:\Users\Stewi\Source\Repos\air2921\FileCryptWeb\FileCryptWeb\Controllers\EnryptionControllers\EncryptionController.cs:line 94
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at FileCryptWeb.JwtTokenMiddleware.Invoke(HttpContext context, FileCryptDbContext dbContext, ITokenService tokenService) in C:\Users\Stewi\Source\Repos\air2921\FileCryptWeb\FileCryptWeb\JwtTokenMiddleware.cs:line 47
         at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
c#
  • 1 个回答
  • 67 Views
Martin Hope
air
Asked: 2023-09-13 21:44:04 +0000 UTC

使用 MemoryStream 时有效的内存使用

  • 5

在我的网站上,为了速度和减少对数据库的请求数量,一些敏感信息(用户加密密钥)将缓存在Redis中。

但是以明文形式将此类信息存储在缓存中是不安全的,因此在存储到缓存中之前,将使用存储在服务器上的单个加密密钥对该信息进行加密。

加密算法将非常简单,使用MemoryStream将加密密钥加载到内存中,以供进一步使用。

而问题是,这样做是否可行,会不会极大地影响性能,因为本质上用户拥有一个32字节长的加密密钥,而这个大小的密钥对内存几乎没有影响,而且即使有一百万用户,那么这仍然对性能几乎没有影响。而且即使考虑到密钥的生命周期为 30 分钟,并且在需要时会存储在缓存中,这仍然不算什么,事实上,MemoryStream 可以放心使用。

但是查看 MemoryStream 的文档,有一个重要的说明:

该类型实现了 IDisposable 接口,但实际上没有任何资源可供处置。这意味着不需要通过直接调用 Dispose() 或使用构造语言(例如 using(在 C# 中)或 using(在 Visual Basic 中))来处理它。

当使用MemoryStream时,Dispose()调用根本没有用,内存永远不会被释放,并且会占用内存,这是什么意思?

现在我再问一个问题:是否值得使用 MemoryStream 来临时存储密钥,或者我们可以考虑其他选择吗?

c#
  • 1 个回答
  • 53 Views
Martin Hope
air
Asked: 2023-09-12 02:28:48 +0000 UTC

没有连接到redis

  • 5

我正在尝试建立从 Redis 到本地主机的连接。

string connectionString = configuration.GetConnectionString("RedisConnection");

_redis = ConnectionMultiplexer.Connect(connectionString); //Исключение

_database = _redis.GetDatabase();

连接字符串本身来自用户机密:

"ConnectionStrings:RedisConnection": "redis://localhost:6379/",

字符串本身肯定不为空

在此输入图像描述

但在 C# 中我得到这个异常:

StackExchange.Redis.RedisConnectionException HResult=0x80131500 Message=无法连接到 Redis 服务器。现在连接时出错。要允许此多路复用器继续重试直到能够连接,请在连接字符串中使用 abortConnect=false 或 AbortOnConnectFail=false; 在你的代码中。源 = StackExchange.Redis StackTrace:位于 StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(ConfigurationOptions 配置、TextWriter 日志、Nullable1 serverType, EndPointCollection endpoints) at StackExchange.Redis.ConnectionMultiplexer.Connect(ConfigurationOptions configuration, TextWriter log) at StackExchange.Redis.ConnectionMultiplexer.Connect(String configuration, TextWriter log) at FileCryptWeb.DataBase.Redis.RedisDbContext..ctor() in C:\Users\Stewi\Source\Repos\air2921\FileCryptWeb\FileCryptWeb\DataBase\Redis\RedisDbContext.cs:line 19 at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.ConstructorInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite,TArgument参数)在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite,ServiceProviderEngineScope范围)在Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine。<>c__Di splayClass2_0.b__0(ServiceProviderEngineScope范围)在 Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(类型 serviceType,ServiceProviderEngineScope serviceProviderEngineScope) 在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,类型 type,类型 requiredBy,布尔 isDefaultParameterRequired) 在 Microsoft.AspNetCore.Mvc.Controllers.Con trollerFactoryProvider。<>c__DisplayClass6_0.g__CreateController|0(ControllerContextcontrollerContext),位于 Microsoft.AspNetCore.Mvc。Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker.InvokeInnerFilterAsync() 处的 Infrastructure.ControllerActionInvoker.Next(State& next、Scope& range、Object& state、Boolean& isCompleted)

尝试启动服务器

C:\Users\Stewi>cd C:\Program Files\Redis

C:\Program Files\Redis>redis-server.exe "C:\Program Files\Redis\redis.windows.conf"
[11340] 12 Sep 01:14:15.298 # Creating Server TCP listening socket *:6379: bind: No error

但在 netstat 中该端口没有监听:

C:\Users\Stewi>netstat

Active Connections

Proto  Local Address          Foreign Address        State

TCP    192.168.0.2:52525      162.159.133.234:https  ESTABLISHED
TCP    192.168.0.2:52791      stackoverflow:https    ESTABLISHED
TCP    192.168.0.2:52917      20.54.37.64:https      ESTABLISHED
TCP    192.168.0.2:53017      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53102      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53132      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53336      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53352      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53353      lb-140-82-112-25-iad:https  ESTABLISHED
TCP    192.168.0.2:53433      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53434      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53437      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53439      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53443      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53445      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53446      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53447      ve1190:9251            TIME_WAIT
TCP    192.168.0.2:53449      132.245.231.0:https    TIME_WAIT
TCP    192.168.0.2:53452      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53453      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53457      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53458      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53459      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53461      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53462      47:https               TIME_WAIT
TCP    192.168.0.2:53463      20.189.173.7:https     TIME_WAIT
TCP    192.168.0.2:53466      62.115.252.59:https    ESTABLISHED
TCP    192.168.0.2:53467      132.245.231.0:https    ESTABLISHED
TCP    192.168.0.2:53469      13.107.246.73:https    ESTABLISHED
TCP    192.168.0.2:53470      52.108.8.254:https     ESTABLISHED
TCP    192.168.0.2:53471      152.199.21.118:https   ESTABLISHED
TCP    192.168.0.2:53472      204.79.197.222:https   ESTABLISHED
TCP    192.168.0.2:53473      20.54.232.160:https    ESTABLISHED
TCP    192.168.0.2:53474      47:https               TIME_WAIT
TCP    192.168.0.2:53475      ve1190:9251            ESTABLISHED
TCP    192.168.0.2:53476      152.199.19.161:https   ESTABLISHED
TCP    192.168.0.2:53477      a23-53-53-206:https    ESTABLISHED
TCP    192.168.0.2:53478      20.42.128.98:https     ESTABLISHED
TCP    192.168.0.2:53479      152.199.19.161:https   ESTABLISHED
TCP    192.168.0.2:53480      a23-53-53-206:https    ESTABLISHED
TCP    192.168.0.2:53481      20.42.128.98:https     ESTABLISHED
TCP    192.168.0.2:53482      13.107.246.73:https    ESTABLISHED
TCP    192.168.0.2:53483      13.69.109.131:https    ESTABLISHED
TCP    192.168.0.2:53484      152.199.19.161:https   ESTABLISHED
TCP    192.168.0.2:53485      13.107.5.88:https      ESTABLISHED
TCP    192.168.0.2:53487      a23-35-104-91:https    ESTABLISHED
TCP    192.168.0.2:53488      80.239.137.145:https   ESTABLISHED
TCP    192.168.0.2:53489      150.171.22.254:https   ESTABLISHED
TCP    192.168.0.2:53491      a23-35-104-91:https    ESTABLISHED
TCP    192.168.0.2:53492      13.107.237.254:https   ESTABLISHED
TCP    192.168.0.2:53493      52.123.128.254:https   ESTABLISHED
TCP    192.168.0.2:53494      13.107.42.254:https    ESTABLISHED
TCP    192.168.0.2:53495      204.79.197.254:https   ESTABLISHED
TCP    192.168.0.2:53496      13.107.18.254:https    ESTABLISHED
TCP    192.168.0.2:53497      152.199.19.161:https   ESTABLISHED
TCP    192.168.0.2:53498      13.107.246.254:https   ESTABLISHED
TCP    192.168.0.2:53499      13.107.42.14:https     ESTABLISHED
TCP    192.168.0.2:53500      104.215.5.225:https    ESTABLISHED
TCP    192.168.0.2:53501      13.107.253.254:https   ESTABLISHED
TCP    192.168.0.2:53502      20.141.10.208:https    ESTABLISHED
TCP    192.168.0.2:53503      152.199.19.161:https   ESTABLISHED
TCP    192.168.0.2:53504      20.190.181.5:https     ESTABLISHED
TCP    192.168.0.2:53505      13.107.42.18:https     ESTABLISHED
TCP    192.168.0.2:53506      a23-53-53-206:https    ESTABLISHED
TCP    192.168.0.2:53507      13.107.42.18:https     ESTABLISHED
TCP    192.168.0.2:53508      13.107.42.18:https     ESTABLISHED
TCP    192.168.0.2:53572      lr-in-f188:5228        ESTABLISHED
TCP    192.168.0.2:54929      40:https               ESTABLISHED
TCP    192.168.0.2:64183      124:4070               ESTABLISHED
TCP    192.168.0.2:64208      47:https               ESTABLISHED
TCP    [::1]:2619             DESKTOP-DRISJ7T:62737  ESTABLISHED
TCP    [::1]:62737            DESKTOP-DRISJ7T:2619   ESTABLISHED

我的redis版本

Redis server v=3.0.504 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=a4f7a6e86f2d60b3
c#
  • 1 个回答
  • 57 Views
Martin Hope
air
Asked: 2023-09-08 17:23:21 +0000 UTC

Null 到达 IFormFile

  • 5

有这样一种控制器测试方法

    [HttpPost]
    public async Task<IActionResult> UploadFile(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return Content("file not selected");

        var ms = new MemoryStream();
        file.OpenReadStream().CopyTo(ms);
        byte[] fileBytes = ms.ToArray();

        try
        {
            Console.WriteLine($"ClamAV scan begin for file {file.FileName}");
            var clam = new ClamClient("localhost", 3310);
            var scanResult = await clam.SendAndScanFileAsync(fileBytes);
            switch (scanResult.Result)
            {
                case ClamScanResults.Clean:
                    Console.WriteLine($"The file is clean! ScanResult: {scanResult.RawResult}");
                    break;
                case ClamScanResults.VirusDetected:
                    Console.WriteLine($"Virus Found! Virus name: {scanResult.InfectedFiles.FirstOrDefault().VirusName}");
                    break;
                case ClamScanResults.Error:
                    Console.WriteLine($"An error occurred while scanning the file! ScanResult: {scanResult.RawResult}");
                    break;
                case ClamScanResults.Unknown:
                    Console.WriteLine($"Unknown scan result while scanning the file! ScanResult: {scanResult.RawResult}");
                    break;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"ClamAV Scan Exception: {ex.Message}");
        }

        return RedirectToAction("Index");
    }

它接受一个文件进行扫描,它接受 IFormFile,并且文件最大为 20MB+ - 一切都很好,它们被下载并扫描,但是当我尝试上传一个重 47MB 的文件时,我在 IFormFile 中得到 null,我尝试设置一个轻微的值延迟(我不知道我希望什么),尝试将其添加到 Program 类中

        builder.Services.Configure<FormOptions>(options =>
        {
            options.MultipartBodyLengthLimit = 100 * 1024 * 1024;
        });

但这也没有帮助,很可能是限制文件大小的问题,如下所示:

如何增加iis express中上传到服务器的附件的最大大小?

但是,我根本没有答案中引用的这个文件,并且项目中根本没有 XML 文件。告诉我需要做什么...

c#
  • 1 个回答
  • 38 Views
Martin Hope
air
Asked: 2023-09-08 03:05:20 +0000 UTC

CRUD操作接口分离原则

  • 6

问题很简单。您应该为所有 CRUD 操作创建一个接口,还是应该为每种类型的操作保留一个接口?

总共有 4 个接口(创建、读取、更新、删除),每个接口有 4 个类。或者创建一个包含所有CRUD操作的接口,以及一个实现所有这些接口的类(这些类中总共有13个方法),这不是与ISP相矛盾吗?

现在我把它排列成这样(如果屏幕截图不合适,我很抱歉):

在此输入图像描述

在此输入图像描述

这就是它在依赖容器中的位置:

        builder.Services.AddScoped<ICreateUser, CreateUser>();
        builder.Services.AddScoped<IDeleteUser, DeleteUser>();
        builder.Services.AddScoped<IReadUser, ReadUser>();
        builder.Services.AddScoped<IUpdateUser, UpdateUser>();

PS如果我没有指出什么,请指出具体是什么;没有必要立即否决它。

c#
  • 1 个回答
  • 62 Views
Martin Hope
air
Asked: 2023-09-07 10:06:19 +0000 UTC

42P07:关系“用户”已经存在

  • 4

我尝试通过迁移添加新表,但收到用户已存在的错误。

我的操作顺序如下: dotnet ef 迁移删除 -> 通过 postgres 终端手动清除数据库 -> dotnet ef 迁移添加 InitialMigrations -> dotnet ef 数据库更新(错误!)

虽然数据库本身没有表,但之前也有错误,已经绝望了,我拆除数据库并创建一个新数据库,没有任何表,但是当我尝试更新数据库时,出现以下错误:

失败:Microsoft.EntityFrameworkCore.Database.Command[20102] 执行 DbCommand 失败(17ms)[Parameters=[],CommandType='Text',CommandTimeout='30']

CREATE TABLE users (
id integer GENERATED BY DEFAULT AS IDENTITY,
role text NULL,
username text NULL,
password_hash text NULL,
email text NULL,
encryption_key text NULL,
api_key text NULL,
CONSTRAINT "PK_users" PRIMARY KEY (id)
);

执行 DbCommand 失败(17 毫秒)[参数=[],CommandType='Text',CommandTimeout='30']

CREATE TABLE users (
id integer GENERATED BY DEFAULT AS IDENTITY,
role text NULL,
username text NULL,
password_hash text NULL,
email text NULL,
encryption_key text NULL,
api_key text NULL,
CONSTRAINT "PK_users" PRIMARY KEY (id)
);
Npgsql.PostgresException (0x80004005): 42P07: relation "users" already exists

   at Npgsql.Internal.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|234_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteNonQuery()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
  Exception data:
    Severity: ERROR
    SqlState: 42P07
    MessageText: relation "users" already exists
    File: heap.c
    Line: 1148
    Routine: heap_create_with_catalog

42P07: relation "users" already exists

虽然数据库是干净的并且不包含任何表

在此输入图像描述

这是文件模型:

public class UserFileModel
{
    public string? fileId { get; set; }
    public string? file_path { get; set; }
    public string? file_name { get; set; }
    public string? status { get; set; }
    public int? result_scan { get; set; }
    public string error_message { get; set; }
    public string enc_time { get; set; }
    public string dec_time { get; set; }
    public string upload_time { get; set; }
    public string download_time { get; set; }

    public int? id { get; set; } // Внешний ключ

    [ForeignKey("id")]
    public UserModel User { get; set; } // Навигационное свойство
}

这是用户模型

public class UserModel
{
    public int? id { get; set; }
    public string? role { get; set; }
    public string? username { get; set; }
    public string? password_hash { get; set; }
    public string? email { get; set; }
    public string? encryption_key { get; set; }
    public string? api_key { get; set; }
}

这是上下文类

public class FileCryptDbContext : DbContext
{
    public DbSet<UserModel> Users { get; set; }
    public DbSet<UserFileModel> Files { get; set; }

    public FileCryptDbContext(DbContextOptions<FileCryptDbContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserFileModel>()
            .HasOne(f => f.User)
            .WithMany()
            .HasForeignKey(f => f.id);
    }
}

这是迁移过程中创建的 ModelSnapShot。

[DbContext(typeof(FileCryptDbContext))]
partial class FileCryptDbContextModelSnapshot : ModelSnapshot
{
    protected override void BuildModel(ModelBuilder modelBuilder)
    {
#pragma warning disable 612, 618
        modelBuilder
            .HasAnnotation("ProductVersion", "7.0.10")
            .HasAnnotation("Relational:MaxIdentifierLength", 63);

        NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);

        modelBuilder.Entity("FileCryptWeb.Models.UserFileModel", b =>
            {
                b.Property<int?>("id")
                    .HasColumnType("integer");

                b.Property<string>("dec_time")
                    .IsRequired()
                    .HasColumnType("text");

                b.Property<string>("download_time")
                    .IsRequired()
                    .HasColumnType("text");

                b.Property<string>("enc_time")
                    .IsRequired()
                    .HasColumnType("text");

                b.Property<string>("error_message")
                    .IsRequired()
                    .HasColumnType("text");

                b.Property<string>("fileId")
                    .HasColumnType("text");

                b.Property<string>("file_name")
                    .HasColumnType("text");

                b.Property<string>("file_path")
                    .HasColumnType("text");

                b.Property<int?>("result_scan")
                    .HasColumnType("integer");

                b.Property<string>("status")
                    .HasColumnType("text");

                b.Property<string>("upload_time")
                    .IsRequired()
                    .HasColumnType("text");

                b.HasKey("id");

                b.ToTable("files");
            });

        modelBuilder.Entity("FileCryptWeb.Models.UserModel", b =>
            {
                b.Property<int?>("id")
                    .ValueGeneratedOnAdd()
                    .HasColumnType("integer");

                NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int?>("id"));

                b.Property<string>("api_key")
                    .HasColumnType("text");

                b.Property<string>("email")
                    .HasColumnType("text");

                b.Property<string>("encryption_key")
                    .HasColumnType("text");

                b.Property<string>("password_hash")
                    .HasColumnType("text");

                b.Property<string>("role")
                    .HasColumnType("text");

                b.Property<string>("username")
                    .HasColumnType("text");

                b.HasKey("id");

                b.ToTable("users");
            });

        modelBuilder.Entity("FileCryptWeb.Models.UserFileModel", b =>
            {
                b.HasOne("FileCryptWeb.Models.UserModel", "User")
                    .WithMany()
                    .HasForeignKey("id")
                    .OnDelete(DeleteBehavior.Cascade)
                    .IsRequired();

                b.Navigation("User");
            });
#pragma warning restore 612, 618
    }
}
c#
  • 1 个回答
  • 35 Views
Martin Hope
air
Asked: 2023-08-24 02:47:30 +0000 UTC

如何读取 IFormFile

  • 5

如何读取 IFormFile 文件,而不需要将文件上传到服务器,也不需要使用 MemoryStream。

有一种将文件上传到服务器的方法:

    protected async Task<IActionResult> UploadFile(
        IFormFile file,
        string apiKey,
        string folderForCryptionFile)
    {
        try
        {
            if (file == null || file.Length <= 0)
            {
                return BadRequest(new { message = "No file selected for upload" });
            }

            var userid = await _readUser.ReadUserIdByApiKey(apiKey);
            var uploadsFolder = Path.Combine(folderForCryptionFile, $"User({userid})");
            if (!Directory.Exists(uploadsFolder))
            {
                Directory.CreateDirectory(uploadsFolder);
            }

            double totalSizeFolder = GetSize.GetFolderSizeInMb(uploadsFolder);
            double totalSizeFile = GetSize.GetFileSizeInMb(file);
            if (totalSizeFolder + totalSizeFile > 75.0)
            {
                return BadRequest("The size of an individual folder should not exceed 75 MB");
            }

            var uniqueFileName = Guid.NewGuid().ToString() + "_" + file.FileName;
            var filePath = Path.Combine(uploadsFolder, uniqueFileName);

            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            return Ok();
        }
        catch (InvalidOperationException)
        {
            return BadRequest("User with this API key not found");
        }
        catch (Exception ex)
        {
            return Problem(ex.Message);
        }
    }

和这样的控制器方法:

    [HttpPost("Upload")]
    public async Task<IActionResult> UploadFiles(List<IFormFile> files, [FromHeader(Name = "ApiKey")] string apiKey)
    {
        var totalFiles = files.Count;
        var successFiles = 0;

        foreach (var file in files)
        {
            if (allowedFiles.allowedContentTypes.Contains(file.ContentType))
            {
                await UploadFile(file, apiKey, _paths.FolderForEncryptionFiles);
                successFiles++;
            }
            else
            {
                continue;
            }
        }

        if (successFiles == totalFiles)
        {
            return Ok($"All {totalFiles} files were successfully uploaded and saved.");
        }
        else if (successFiles > 0 && successFiles != totalFiles)
        {
            return Ok($"{successFiles} out of {totalFiles} files were successfully uploaded and saved.");
        }
        else
        {
            return BadRequest("No files were successfully uploaded.");
        }
    }

可以看到,它以 IFormFile 的形式接受来自客户端的文件,在控制器中,在加载文件之前,需要读取文件并将文件数据发送给第三方 API,并且由于无法将文件上传到服务器,因此无法使用File.OpenRead,所以选项仍然是MemoryStream,但它会使用大量内存,并且如果有很多文件和用户,然后使用 Dispose 将不再有帮助。

还有其他选项可以读取该文件吗?

c#
  • 1 个回答
  • 37 Views
Martin Hope
air
Asked: 2023-08-23 18:41:03 +0000 UTC

访问 VirusTotal API 时出现问题 (403)

  • 6

我尝试向 VtAPI 发送 POST 请求来扫描文件,但收到 403 错误

钥匙完全正确,我检查了好几遍。

这是一个包含使用 API 密钥示例的页面https://developers.virustotal.com/v2.0/reference/file-scan

这是我发送 API 请求的方式:

    static async Task Main(string[] args)
    {
        var apiKey = "";
        var filePath = "C:/exmpl/exmpl.jpg";

        var result = await ScanFileWithVirusTotal(apiKey, filePath);
        Console.WriteLine(result);
    }

    static async Task<string> ScanFileWithVirusTotal(string apiKey, string filePath)
    {
        byte[] fileBytes = File.ReadAllBytes(filePath);
        string fileBase64 = Convert.ToBase64String(fileBytes);

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var requestContent = new StringContent($"{{\"apikey\":\"{apiKey}\",\"file\":\"{fileBase64}\"}}");
            requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var requestUri = new Uri("https://www.virustotal.com/vtapi/v2/file/scan");

            using (var response = await client.PostAsync(requestUri, requestContent))
            {
                response.EnsureSuccessStatusCode();
                var responseBody = await response.Content.ReadAsStringAsync();
                return responseBody;
            }
        }
    }
c#
  • 1 个回答
  • 36 Views
Martin Hope
air
Asked: 2023-07-11 00:57:33 +0000 UTC

Use 方法在 Asp.NET core 中的工作原理

  • 6

我刚刚开始学习 ASP.NET core 7.0,我有一个问题。有一个 Map 方法,它需要在站点周围进行路由(我或多或少理解这一点),并且有一个 Use 方法充当初始(第一个)请求处理程序并允许您管理中间件。我想象在访问网站时使用此方法作为首页,例如,在看到主页之前,或者一般来说网站的任何页面,您需要进行身份验证,并且只有当用户通过身份验证时,然后等待next.Invoke() 就可以了;并且站点的所有页面都会显示,如果不显示,认证页面就会一直挂掉。

我不明白我是否正确地表达了它的用途。我还想看到 Use 在实际项目中的使用,而不是在简单的示例中。

我将不胜感激任何帮助,特别是如果有项目中的使用示例。

c#
  • 1 个回答
  • 42 Views
Martin Hope
air
Asked: 2023-06-15 16:52:44 +0000 UTC

加密占用大量内存

  • 6

有这样的加密和覆盖文件的方法

    private static byte[] Encrypt(byte[] fileData, byte[] key, byte[] salt)
    {
        using (Aes aes = Aes.Create())
        {
            using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(key, salt, 10000))
            {
                aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
            }

            aes.GenerateIV();
            byte[] iv = aes.IV;

            using (MemoryStream encryptedStream = new MemoryStream())
            {
                encryptedStream.Write(salt, 0, salt.Length);
                encryptedStream.Write(iv, 0, iv.Length);

                using (CryptoStream cryptoStream = new CryptoStream(encryptedStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cryptoStream.Write(fileData, 0, fileData.Length);
                    cryptoStream.FlushFinalBlock();
                }

                byte[] encryptedData = encryptedStream.ToArray();
                return encryptedData;
            }
        }
    }

    public void EncryptFile(string filePath, byte[] key, byte[] salt)
    {
        byte[] data = File.ReadAllBytes(filePath);
        byte[] encryptedData = Encrypt(data, key, salt);

        using (FileStream encryptedFileStream = new FileStream(filePath, FileMode.Create))
        {
            encryptedFileStream.Write(encryptedData, 0, encryptedData.Length);
        }
        Console.WriteLine($"Файл {filePath} был успешно зашифрован.");

        data = null;
        encryptedData = null;
        GC.Collect();
    }

以及解密和覆盖文件的方法

    private static byte[] Decrypt(byte[] encryptedData, byte[] key, byte[] salt)
    {
        using (Aes aes = Aes.Create())
        {
            using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(key, salt, 10000))
            {
                aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
            }

            byte[] iv = new byte[aes.IV.Length];
            Buffer.BlockCopy(encryptedData, salt.Length, iv, 0, iv.Length);
            aes.IV = iv;

            using (MemoryStream encryptedStream = new MemoryStream(encryptedData, salt.Length + iv.Length, encryptedData.Length - salt.Length - iv.Length))
            using (MemoryStream decryptedStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(encryptedStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    cryptoStream.CopyTo(decryptedStream);
                }

                byte[] decryptedData = decryptedStream.ToArray();
                return decryptedData;
            }
        }
    }

    public void DecryptFile(string filePath, byte[] key, byte[] salt)
    {
        byte[] encryptedData = File.ReadAllBytes(filePath);
        byte[] decryptedData = Decrypt(encryptedData, key, salt);

        using (MemoryStream decryptedStream = new MemoryStream(decryptedData))
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                decryptedStream.CopyTo(fs);
            }
        }
        Console.WriteLine($"Файл {filePath} был успешно расшифрован.");

        encryptedData = null;
        decryptedData = null;
        GC.Collect();
    }

而我的问题是,当你开始加密一个200mb的目录过程时,使用了大约700mb的RAM,但在后续操作过程中,使用的内存没有增加或减少,这是否正常。也就是说,好像有一块保留内存是在第一次操作时分配的,之后用于所有后续操作,这是正常的,还是我的代码存在内存泄漏?

c#
  • 2 个回答
  • 111 Views
Martin Hope
air
Asked: 2023-06-15 15:52:01 +0000 UTC

C# 垃圾收集器

  • 9

是否有可能以某种方式跟踪 Visual Studio 2022 中垃圾收集器的工作(即一般来说,它发布的所有工作,它以什么顺序执行等)

c#
  • 1 个回答
  • 61 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5