RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

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

XelaNimed's questions

Martin Hope
XelaNimed
Asked: 2024-07-11 19:20:46 +0000 UTC

以编程方式为基本类型创建值验证器

  • 4

我需要根据动态定义的约束和规则检查各种基元类型及其集合的值。这对于检查/监控一组 CNC 机器的返回值是必要的,根据机器/订单/时间/员工/月相等,这些机器可能有不同的可接受值范围。检查还用于确定后续事件生成是否超出关键指标的阈值。
不幸的是,由于无法克服的情况,在数据库中保存值的选项是不可接受的,因此,目前正在考虑以下选项......

选项一:你自己的“自行车”

编写你自己的“自行车”,希望你有足够的资历和经验来开发一个好的库。


选项 2:实施 Bean 验证 API

与第一种选择一样,唯一的区别是“自行车”将根据一定的规则建造,这将有助于避免方形轮子,但使用/可靠性/维护仍然存在问题。


选项 3:Hibernate 验证器

使用 Bean Validation API(Hibernate Validator),可以动态创建规则。用法示例如下:

<!-- Maven dependencies -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.13.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.cfg.ConstraintMapping;
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.valueextraction.ExtractedValue;
import javax.validation.valueextraction.ValueExtractor;

import org.hibernate.validator.cfg.defs.*;

public class App
{
    public static void main( final String[] args )
    {
        try ( ValidatorFactory factory = Validation
                .byProvider( HibernateValidator.class )
                .configure()
                .addMapping( buildPrimitiveConstraintMapping() )
                .addValueExtractor( new IntegerValueExtractor() )
                .addValueExtractor( new StringValueExtractor() )
                .messageInterpolator( new ParameterMessageInterpolator() )
                .buildValidatorFactory() )
        {
            Validator validator = factory.getValidator();

            validator.validate( 7 )
                .stream()
                .map( ConstraintViolation::getMessage )
                .forEach( System.out::println );
            
            validator.validate( "" )
                .stream()
                .map( ConstraintViolation::getMessage )
                .forEach( System.out::println );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }

    private static ConstraintMapping buildPrimitiveConstraintMapping()
    {
        ConstraintMapping mapping = new DefaultConstraintMapping();

        mapping
            .type( Integer.class )
            .constraint( new NotNullDef() )
            .constraint( new MinDef().value( 18 ) )
            .constraint( new MaxDef().value( 50 ) );

        mapping
            .type( String.class )
            .constraint( new NotNullDef() )
            .constraint( new NotBlankDef() );

        return mapping;
    }

    // Value extractor for Integer
    public static class IntegerValueExtractor
            implements
            ValueExtractor<@ExtractedValue(type = Integer.class) Integer>
    {
        @Override
        public void extractValues(
            Integer originalValue,
            ValueReceiver receiver )
        {
            receiver.value( null, originalValue );
        }
    }

    // Value extractor for String
    public static class StringValueExtractor
            implements
            ValueExtractor<@ExtractedValue(type = String.class) String>
    {
        @Override
        public void extractValues(
            String originalValue,
            ValueReceiver receiver )
        {
            receiver.value( null, originalValue );
        }
    }

}

习惯上如何“根据风水”解决此类问题?所选库对于解决任务/问题是否多余?

java
  • 1 个回答
  • 28 Views
Martin Hope
XelaNimed
Asked: 2024-03-02 04:27:51 +0000 UTC

从本机原型生成 Java 项目时,不会创建项目文件,并且包名称中不会使用artifactId

  • 6

有一个用于生成 Java 项目的原型 Maven 项目,它是使用org.apache.maven.archetypes: [email protected]创建的。问题是,当使用创建的原型生成项目时,创建了文件结构,但.project创建的项目的根目录中没有文件。另外,生成时指定的应包含和$package组合的包名的变量中没有,并且创建的文件结构中也没有 对应的目录。 换句话说,当生成这样的项目时:groupIdartifactIdartifactIdartifactId

mvn archetype:generate \
-DarchetypeGroupId=io.github.xelanimed \
-DarchetypeArtifactId=java11-junit5 \
-DarchetypeVersion=0.0.1 \
-DgroupId=com.example \
-DartifactId=sandbox-test

App.java位于目录中的文件中生成的包名称src/main/java/com/example是com.example,即
src/main/java/com/example/sandbox_test/App.java而不是我们得到的预期文件
src/main/java/com/example/App.java

我在本地存储库中安装了原型,如下所示:mvn clean install archetype:update-local-catalog等等mvn clean install,并“手动”删除旧工件。

我已经打破了所有的钻石,但我不明白问题是什么,我做错了什么?


使用的指南、资源、有关该主题的链接

  • 创建原型指南
  • Baeldung 的 Maven 原型指南
  • 如何创建自定义 Maven 原型?
  • 原型描述符

原型项目结构

java11-junit5/
├── src/
│   ├── main/
│   │   └── resources/
│   │       ├── archetype-resources/
│   │       │   ├── src/
│   │       │   │   ├── main/
│   │       │   │   │   ├── java/
│   │       │   │   │   │   └── App.java
│   │       │   │   │   └── resources/
│   │       │   │   │       ├── filterable/
│   │       │   │   │       │   └── README.md
│   │       │   │   │       └── logback-test.xml
│   │       │   │   └── test/
│   │       │   │       ├── java/
│   │       │   │       │   ├── AppTest.java
│   │       │   │       │   └── TestBase.java
│   │       │   │       └── resources
│   │       │   ├── .gitignore
│   │       │   ├── pom.xml
│   │       │   └── README.md
│   │       └── META-INF/
│   │           └── maven/
│   │               └── archetype-metadata.xml
│   └── test/
│       └── resources/
│           └── projects/
│               └── it-basic/
│                   ├── archetype.properties
│                   └── goal.txt
├── target
├── .project
├── pom.xml
└── README.md

来源

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project 
xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>io.github.xelanimed</groupId>
    <artifactId>java11-junit5</artifactId>
    <version>0.0.1</version>
    <packaging>maven-archetype</packaging>

    <name>Archetype - java11-junit5</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <build>
        <extensions>
            <extension>
                <groupId>org.apache.maven.archetype</groupId>
                <artifactId>archetype-packaging</artifactId>
                <version>3.2.1</version>
            </extension>
        </extensions>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>3.3.0</version>
                    <executions>
                        <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.3.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-archetype-plugin</artifactId>
                    <version>3.2.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.3.1</version>
                    <configuration>
                        <addDefaultExcludes>false</addDefaultExcludes>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>3.1.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>3.1.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

。项目

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>java11-junit5</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.m2e.core.maven2Builder</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.m2e.core.maven2Nature</nature>
    </natures>
</projectDescription>

src/main/resources/META-INF/maven/archetype-metadata.xml

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor
    xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
    name="java11-junit5">

    <requiredProperties>
        <requiredProperty key="groupId" />
        <requiredProperty key="artifactId" />
        <requiredProperty key="version">
          <defaultValue>0.0.1-SNAPSHOT</defaultValue>
        </requiredProperty>
    </requiredProperties>

  <fileSets>
    <fileSet filtered="true" packaged="true">
      <directory>src/main/java</directory>
    </fileSet>
    <fileSet filtered="true" packaged="true">
      <directory>src/test/java</directory>
    </fileSet>
    <fileSet filtered="true" packaged="false">
        <directory>src/main/resources</directory>
    </fileSet>
    <fileSet filtered="true" packaged="false">
        <directory>src/test/resources</directory>
    </fileSet>
  </fileSets>
</archetype-descriptor>

src/main/resources/archetype-resources/src/main/java/App.java

package $package;

public class App
{
    /**
     * Using example:
     * {@snippet file="AppTest.java" region="main"}
     */
    public static void main( final String[] args )
    {
        System.out.println( "args: " + java.util.Arrays.toString( args ) );
    }
}

src/main/java/com/example/App.java

package com.example;

public class App
{
    /**
     * Using example:
     * {@snippet file="AppTest.java" region="main"}
     */
    public static void main( final String[] args )
    {
        System.out.println( "args: " + java.util.Arrays.toString( args ) );
    }
}
java
  • 1 个回答
  • 24 Views
Martin Hope
XelaNimed
Asked: 2023-11-17 18:48:39 +0000 UTC

如何使用参数数组在 MS SQL 服务器端格式化文本?

  • 7

使用MS SQL 2019。
本地化的消息模板存储在一张表中(例如,“处理文件%s时发生错误。”)。
参数以 JSON 形式存储在另一个表中,因为 参数的数量因消息而异。
换句话说,我们获取字符串格式,获取参数,并使用String.format方法在客户端格式化所有内容。
我的任务是将消息格式“传输”到 MS SQL 服务器端。使用FORMATMESSAGE函数,您可以格式化文本,但问题是参数数量不同,并且如何传递参数数组尚不清楚,原则上这是否可能?

DECLARE @json NVARCHAR(MAX);
SET @json = '[1,"abc","def"]';

SELECT FORMATMESSAGE (
    'First arg: %s, second arg: %s, last arg: %s',
    JSON_VALUE( @json, '$')
)
-- выводит: First arg: (null), second arg: (null), last arg: (null)

SELECT FORMATMESSAGE (
    'First arg: %s, second arg: %s, last arg: %s',
    JSON_VALUE( @json, '$[0]'),
    JSON_VALUE( @json, '$[1]'),
    JSON_VALUE( @json, '$[2]')
)
-- выводит: First arg: 1, second arg: abc, last arg: def

如何使用参数数组在 MS SQL 服务器端格式化文本?

sql
  • 1 个回答
  • 34 Views
Martin Hope
XelaNimed
Asked: 2022-10-01 00:15:22 +0000 UTC

如何自动更新 README 文件的内容?

  • 1

有一个 README.md 文件,其中包含转换为 pom.xml 文件值的各种文本占位符。该文件位于路径上{project.basedir}/doc/README.md,并且在构建项目时,它由maven-resources-plugin 插件处理,该插件将文本占位符转换并将其复制到项目根目录,并在下一步中复制到目标目录(所以它也在 JAR 根目录中):

README.md 文件的内容示例:

# ${project.name}

${project.description}

[[_TOC_]]

## Used Maven Dependencies

- [JUnit](https://junit.org/junit5/docs/${junit}/api/) v.${junit}
- [SELF4J](https://www.javadoc.io/static/org.slf4j/slf4j-api/${slf4j}/index.html) v.${slf4j}
- ...

## Build

Compiled and built at ${timestamp} with:

- Java: ${java.version}
- Maven: ${maven.version}

```xml
<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>${project.artifactId}</artifactId>
    <version>${project.version}</version>
</dependency>
```

在 pom.xml 文件中,处理配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  <!-- ... -->
  <properties>
    <timestamp>${maven.build.timestamp}</timestamp>
    <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
    <!-- ... -->
  </properties>
  <!-- ... -->
  <build>
    <!-- ... -->
    <plugins>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.1.0</version>
        <executions>
          <execution>
            <id>replace-placeholders-in-readme</id>
            <phase>validate</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.basedir}</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.basedir}/doc</directory>
                  <includes>
                    <include>README.md</include>
                  </includes>
                  <filtering>true</filtering>
                </resource>
              </resources>
              <encoding>UTF-8</encoding>
            </configuration>
          </execution>
          <execution>
            <id>copy-readme-to-output</id>
            <phase>compile</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.outputDirectory}</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.basedir}</directory>
                  <includes>
                    <include>README.md</include>
                  </includes>
                </resource>
              </resources>
              <encoding>UTF-8</encoding>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

问题在于,为了执行所有这些转换,必须通过 maven(例如mvn verify)在本地机器上构建,因为 否则,修改后的 README.md 文件将出现在程序集/JAR 文件中,但不在存储库中。例如,在 pom.xml 中某个依赖项的版本发生了变化,而在 README.md 文件中使用了旧版本/引用。

问题:是否有可能以任何方式配置 README.md 文件的自动生成,即使在本地机器上,甚至在 GitLab 端(在 gitlab-ci.yml 中注册)?理想情况下,我们希望在每次提交时生成一个文件并自动将其“推送”到存储库中。


相关链接

  • Maven 资源插件
java maven
  • 1 个回答
  • 57 Views
Martin Hope
XelaNimed
Asked: 2022-09-30 23:14:24 +0000 UTC

在 JUnit 测试中使用身份验证数据

  • 0

有一个使用 Maven 插件openapi-generator-maven-plugin生成的 Maven REST API 客户端项目。测试也在 GitLab 端生成和运行。GitLab 版本 13.12.15 安装在企业内部网络的 Windows 机器上。REST API 中的身份验证由 Bearer 令牌执行,当然,在执行测试期间它必须存在。GitLab 的配置方式使得许多员工可以访问代码,并且只有管理员可以访问存储库设置。

问题:如何使用 Bearer 令牌,使其在执行测试期间可用,但同时它不以开放形式出现在代码中?


有一个想法为此使用GitLab CI / CD 变量,因为在变量设置中您可以指定需要在日志中隐藏变量的值,但是如何在 JUnit 测试中传递/使用这个值?

java junit
  • 1 个回答
  • 12 Views
Martin Hope
XelaNimed
Asked: 2022-06-25 22:31:08 +0000 UTC

java.util.Properties.entrySet 可以包含空值吗?

  • 0

在旧代码中,当迭代 java.util.Properties 中的 entrySet 时,有一个地方需要对 null 进行大量检查:

private void createMaps(java.util.Properties properties)
{
    for(Entry<Object, Object> entry : properties.entrySet())
    {
        if(null == entry) continue;

        if(null == entry.getKey() || null == entry.getValue()) continue;

        String propertyKey = entry.getKey().toString();
        String propertyValue = entry.getValue().toString();

        if(null == propertyKey || null == propertyValue) continue;

        // ...
    }
}

在这方面,出现了几个问题 - 是否会出现以下情况:

  1. 条目为空?
  2. entry.getKey()/entry.getValue() 的返回值为空?
  3. 转换为字符串 entry.getKey/getValue().toString() 的结果是 null 吗?

我不知道这是否与问题相关,但我最好澄清一下属性是从具有 .properties 扩展名的文件中加载的,如下所示:

public static Properties getProperties(String filePath) throws FileNotFoundException, IOException
{
    Properties properties = new Properties();
    try(FileInputStream fis = new FileInputStream(filePath))
    {
        properties.load(fis);
    }
    return properties;
}
java
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2022-10-01 17:37:23 +0000 UTC

如何测试泛型方法?

  • 1

在 Eclipse 2021-09 上使用 JUnit 4.12 测试getPatches(Object, Object)的公共类中有一个静态方法:JsonUtil

import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public static List<PatchOperation> getPatches(
    @Nonnull Object oldData,
    @Nonnull Object newData)
    throws IOException
{
    List<PatchOperation> _patchOperations = new ArrayList<>();
    ObjectMapper objectMapper = new ObjectMapper();

    String _oldDataJson = objectMapper.writeValueAsString(oldData);
    String _newDataJson = objectMapper.writeValueAsString(newData);

    JsonNode _oldJsonNode = objectMapper.readTree(_oldDataJson);
    JsonNode _newJsonNode = objectMapper.readTree(_newDataJson);

    JsonNode _patchData = com.github.fge.jsonpatch.diff.JsonDiff.asJson(_oldJsonNode, _newJsonNode);
    if (_patchData != null)
    {
        _patchOperations = objectMapper.convertValue(_patchData, new TypeReference<List<PatchOperation>>(){});
    }

    return _patchOperations;
}

这里,PatchOperation只是一个 POJO 类,用于反序列化JSON-Patch(参见RFC6902),用于对服务器的PATCH 请求:

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PatchOperation implements Serializable
{
    private static final long serialVersionUID = 9999999999999999999L;
    
    @JsonProperty("op")
    public String Operation;
    
    @JsonProperty("path")
    public String Path;
    
    @JsonProperty("value")
    public Object Value;
    
    @JsonProperty("from")
    public String From;
    
    @Override
    public String toString() 
    {
        try
        {
            return new ObjectMapper().writeValueAsString(this);
        }
        catch ( JsonProcessingException e )
        {
            return super.toString();
        }
    }
}

方法的 JUnit 测试getPatches:

@Test public final void getPatchesTest()
            throws JsonProcessingException, IOException
{
    PatchTestItem _itemOne = new PatchTestItem();
    _itemOne.id = "ABC123";
    _itemOne.active = true;
    _itemOne.value = "First value";

    PatchTestItem _itemTwo = new PatchTestItem();
    _itemTwo.id = "ABC123";
    _itemTwo.active = true;
    _itemTwo.value = "Updated value";

    java.util.List<PatchOperation> _patches = JsonUtil.getPatches(_itemOne, _itemTwo);

    Assert.assertNotNull(_patches);
    Assert.assertEquals(1, _patches.size());
    // в следующей строке выбрасывает ошибку при тестировании обобщённого метода
    Assert.assertEquals("replace", _patches.get(0).Operation);
    Assert.assertEquals("/value", _patches.get(0).Path);
    Assert.assertEquals(_itemTwo.value, _patches.get(0).Value.toString());
    
    _itemTwo.value = _itemOne.value;
    _patches = JsonUtil.getPatches(_itemOne, _itemTwo);
    
    Assert.assertNotNull(_patches);
    Assert.assertEquals(0, _patches.size());
    
    _itemTwo.active = false;
    _itemTwo.value = "Updated value again";
    _patches = JsonUtil.getPatches(_itemOne, _itemTwo);
    
    Assert.assertNotNull(_patches);
}

测试正在运行,以这种形式一切都很好。
现在决定使用通用方法如下:

public static <T> List<T> getPatches(
    @Nonnull Object oldData,
    @Nonnull Object newData)
    throws IOException
{
    List<T> _patchOperations = new ArrayList<>();
    ObjectMapper objectMapper = new ObjectMapper();

    String _oldDataJson = objectMapper.writeValueAsString(oldData);
    String _newDataJson = objectMapper.writeValueAsString(newData);

    JsonNode _oldJsonNode = objectMapper.readTree(_oldDataJson);
    JsonNode _newJsonNode = objectMapper.readTree(_newDataJson);

    JsonNode _patchData = com.github.fge.jsonpatch.diff.JsonDiff.asJson(_oldJsonNode, _newJsonNode);
    if (_patchData != null)
    {
        _patchOperations = objectMapper.convertValue(_patchData, new TypeReference<List<T>>(){});
    }

    return _patchOperations;
}

上面的选项没有通过测试 - 它给出错误“找不到源”并掉入日志:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx.xxx.xxx.xxx.xxx.PatchOperation
    at xxx.xxx.xxx.xxx.xxx.JsonUtilTest.getPatchesTest(JsonUtilTest.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

当然,我知道问题是 JUnit 找不到类型,但是我应该如何以及如何更改以使测试运行?

java
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2022-03-25 21:47:50 +0000 UTC

如何自动使 DataGridView 中的行高适合单元格内容?

  • 1

.Net 5 上有一个带有 DataGridView 的 WinForms 项目。我需要以编程方式更改表格中行的高度(除此之外,设置的值保存在用户的配置中,并在加载表单时应用于 DataGridView)。为了解决这个问题,DataGridView 实例属性AutoSizeRowsMo​​de和DefaultCellStyle的值。WrapMode 以编程方式更改如下内容:

private void setWrapOn()
{
    dataGridView.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
    dataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
    dataGridView.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells);
}
private void setWrapOff()
{
    dataGridView.DefaultCellStyle.WrapMode = DataGridViewTriState.NotSet;
    dataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
    dataGridView.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells);
}

不是说没有效果: DataGridView AutoSizeRowsMo​​de

如您所见,它仅在一个方向上起作用,即 如果在加载表单时设置了平移和自动选择行高,则根据需要显示。当您关闭行翻译和自动选择时,一切正常,但不想朝相反的方向发展。
我尝试在设置这样的值后更新表(在各种序列和选项中):

dataGridView.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells);
dataGridView.Invalidate();
dataGridView.Refresh();
dataGridView.Update();
dataGridView.Visible = false;
dataGridView.Visible = true;

我还尝试从 DataGridView 继承来调用受保护的方法AutoResizeRow(DataGridViewAutoSizeRowsMo​​de, Boolean)。假设当作为第二个参数传递时,true新高度将根据列的当前宽度计算。
还尝试更新数据绑定也没有效果。

如何以编程方式启用和禁用 DataGridView 中的自动行高调整?

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-07-20 21:50:23 +0000 UTC

如何以编程方式向用户配置添加和读取新属性?

  • 1

任务是为本地计算机上程序的每个用户打开和关闭时保存和设置 WinFroms 应用程序窗口的大小。为此,在表单的基类中添加了几个方法,这些方法在打开和关闭表单时被调用:

// вызывается при открытии формы
private void _setFormSize()
{
    Type t = GetType();
    string propName = $"{t.Name}_FormSize";
    try
    {
        // никогда не находит и выбрасывает исключение
        // System.Configuration.SettingsPropertyNotFoundException
        // "The settings property 'FormMain_FormSize' was not found."
        var formSize = (Size)Properties.Settings.Default[propName];
        if (formSize.Width > 0 && formSize.Height > 0)
        {
            Size = formSize;
        }
    }
    catch (Exception ex)
    {
        var baseProp = Properties.Settings.Default.Properties["FormSizeBase"];
        var prop = new SettingsProperty(propName)
        {
            Name = propName,
            IsReadOnly = false,
            PropertyType = typeof(Size),
            DefaultValue = Size.Empty,
            SerializeAs = SettingsSerializeAs.String,
            // читаю вручную добавленое свойства для получения Provider :(
            // Как создать Provider программно?
            Provider = baseProp.Provider
        };
        // этого аттрибута хватит? Или нужно ещё что-то добавить?
        prop.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
        
        Properties.Settings.Default.Properties.Add(prop);
        Properties.Settings.Default.Reload();
        Properties.Settings.Default[propName] = Size;
        Properties.Settings.Default.Save();
    }
}
// вызывется при закрытии формы и корректно сохраняет значение в
// %localappdata%\Company\App.exe_Url_1blablabla\0.0.0.1\user.config
private void _saveFormSize()
{
    Type t = GetType();
    string propName = $"{t.Name}_FormSize";
    Properties.Settings.Default[propName] = Size;
    Properties.Settings.Default.Save();
}

这是 FormSizeBase 在构造函数中的样子:

项目属性 - 设置选项卡

问题是我无法读取该属性,即 该行var formSize = (Size)Properties.Settings.Default[propName];永远找不到该属性,即使%localappdata%\Company\App.exe_Url_1blablabla\0.0.0.1\user.config它存在于文件中:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <AppNamespace.Properties.Settings>
            <setting name="FormSizeBase" serializeAs="String">
                <value>563, 489</value>
            </setting>
            <setting name="FormMain_FormSize" serializeAs="String">
                <value>347, 284</value>
            </setting>
        </AppNamespace.Properties.Settings>
    </userSettings>
</configuration>

我究竟做错了什么?如何从 user.config 中读取配置?


PS:propName定义正确:

调试器中的属性名称

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-02-11 18:48:21 +0000 UTC

枚举应该位于分层架构中的什么位置(在什么级别)?

  • 2

有一个使用分层(洋葱)架构的应用程序框架。目前,VisualStudio 中的解决方案结构如下所示:

RootNs (Solution)
├ Domain (Solution Folder)
│   ├ RootNs.Domain.DataModel
│   ├ RootNs.Domain.Interfaces
│   └ RootNs.Domain.Core
├ Services (Solution Folder)
│   ├ RootNs.Services.DomainServices
│   └ RootNs.Services.ApplicationServices
├ Infrastructure (Solution Folder)
│   └ RootNs.Infrastructure
└ Presentation (Solution Folder)
    └ RootNs.Presentation.Wpf

接口 ( RootNs.Domain.Interfaces) 处于最低/内部级别,理论上不应该依赖任何东西。
但是,在这种情况下,应该在哪里定义用于定义接口的枚举呢?现在我这样做:

// RootNs.Domain.Core
public enum FontFamily
{
  Serif = 0,
  SansSerif = 1,
  Monospace = 2
}

[Flags]
public enum TextDecoration
{
  None = 0,
  Bold = 1,
  Italic = 2,
  Underline = 4
}

// RootNs.Domain.Interfaces
public interface ITextBox
{
  TextDecoration TextDecoration { get; set; }
  FontFamily FontFamily { get; set; }
  // etc.
}

// RootNs.Domain.DataModel
public class TextBox : ITextBox
{
  // interface implementation...
}

在上面的示例中,TextBox它是存储在商店中的实体的一部分。应用程序本身将包含 WPF 和控制台的表示层。目前(根据​​ AK 的建议)我已将接口和域模型中使用的枚举和结构添加到接口和模型中,RootNs.Domain.Core并且已经Core添加为依赖项。这是对的吗?

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-01-24 15:51:50 +0000 UTC

来自不同程序集的二进制序列化和反序列化

  • 4

目前正在移植到 C# 的 VB.Net 程序。旧程序的设置被二进制序列化成bin文件,新程序必须反序列化。在这个阶段,我遇到了无法在新程序中反序列化在旧程序中创建的文件。一开始,显示装配错误。将命名空间重命名为与旧命名空间类似的命名空间后,错误消失,但在BinaryFormatter上调用Deserialize方法时出现了新的System.Runtime.Serialization.SerializationException:

This exception was originally thrown at this call stack:
    System.Runtime.Serialization.ObjectManager.DoFixups()
    System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(System.Runtime.Remoting.Messaging.HeaderHandler, System.Runtime.Serialization.Formatters.Binary.__BinaryParser, bool, bool, System.Runtime.Remoting.Messaging.IMethodCallMessage)
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(System.IO.Stream, System.Runtime.Remoting.Messaging.HeaderHandler, bool, bool, System.Runtime.Remoting.Messaging.IMethodCallMessage)
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(System.IO.Stream)
    Namespace.Serializer.Deserialize<T>(string, T) in Serializer.cs
    Namespace.Serializer.Deserialize<T>(string) in Serializer.cs

在yolosora的帮助下,实现了自己的 SerializationBinder ,现在反序列化通过了,但只包含顶层对象,其属性List<Block> Items为null。

序列化器类

namespace Namespace
{
    public static class Serializer
    {
        public static bool TrySerialize<T>(string path, T instance, out Exception exception)
        {
            exception = null;
            try
            {
                Serialize(path, instance);
                return true;
            }
            catch (Exception ex)
            {
                exception = ex;
                return false;
            }
        }

        public static void Serialize<T>(string path, T instance)
        {
            using (Stream fs = new FileStream(path, FileMode.OpenOrCreate))
            using (Stream gz = new GZipStream(fs, CompressionMode.Compress))
            {
                var bf = new BinaryFormatter();
                bf.Serialize(gz, instance);
            }
        }

        public static bool TryDeserialize<T>(string path, out T result, out Exception exception) where T : new()
        {
            return TryDeserialize(path, out result, new T(), out exception);
        }

        public static bool TryDeserialize<T>(string path, out T result, T defaultInstance, out Exception exception) where T : new()
        {
            exception = null;
            try
            {
                result = Deserialize(path, defaultInstance);
                return true;
            }
            catch(Exception ex)
            {
                exception = ex;
                result = default;
                return false;
            }
        }

        public static T Deserialize<T>(string path, T defaultInstance)
        {
            if (!File.Exists(path))
            {
                return defaultInstance;
            }

            using (Stream fs = new FileStream(path, FileMode.OpenOrCreate))
            using (Stream gz = new GZipStream(fs, CompressionMode.Decompress))
            {
                var bf = new BinaryFormatter();
                bf.Binder = new IgnoreAssemblyBinder();

                // В следующей строке выбрасывалось исключение
                // System.Runtime.Serialization.SerializationException
                return (T)bf.Deserialize(gz);
            }
        }

        public static T Deserialize<T>(string path) where T : new()
        {
            return Deserialize(path, new T());
        }
    }
}

序列化的类是相同的,即 具有相同的类型和属性名称。属性类型也相同。
我发现无论不同程序集中的类型多么相同,它们仍然不同,这就是错误的原因。

有没有办法在另一个程序集中进行二进制反序列化?也许这将有助于在单独的程序集中突出显示具有类型的序列化和反序列化代码?


可反序列化的类和对象

public class Blocks {
  public List<Block> Items { get; set; }
}
public class Block {
  public string Name { get; set; }
  public List<BlockItem> Items { get; set; }
}
public class BlockItem {
  public Color ItemColor { get; set; }
  public OtherNs.FromOtherAssembly { get; set; }
  // остальные свойства имеют обычные типы
  // string, bool, int, double
}

// в WinForms -> Program.cs
public static blocks = Serializer.Deserialize<Blocks>("path/to/bin/file");

序列化绑定器实现

public class IgnoreAssemblyBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        Type type = null;
        if (typeName.StartsWith("System.Collections.Generic.List`1[[Namespace.BlockItem"))
        {
            type = typeof(List<BlockItem>);
        }
        else if (typeName.StartsWith("System.Collections.Generic.List`1[[Namespace.Block"))
        {
            type = typeof(List<Block>);
        }
        else if (typeName == "Namespace.Blocks")
        {
            type = typeof(Blocks);
        }
        else if (typeName == "Namespace.Block")
        {
            type = typeof(Block);
        }
        else if (typeName == "Namespace.BlockItem")
        {
            type = typeof(BlockItem);
        }
        else if (typeName == "System.Drawing.Color")
        {
            type = typeof(System.Drawing.Color);
        }
        else if (typeName == "OtherNs.FromOtherAssembly")
        {
            type = typeof(OtherNs.FromOtherAssembly);
        }
        else
        {
            type = Type.GetType($"{typeName}, {assemblyName}");
        }
        return type;
    }
}

对 BindToType 的每次调用都会从当前程序集中返回正确的类型,但要反序列化的对象的 Items 属性仍为 null。


相关链接

  1. 序列化绑定器
  2. BinaryFormatter 类
  3. BinaryFormatter.Binder 属性
  4. BinaryFormatter.Deserialize 方法

更新

问题是新类中缺少私有字段,即 在新类中,不是显式指定私有字段,而是使用简短的自动属性表示法:

public type PropName { get; set; }
c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-01-13 23:58:28 +0000 UTC

C# 中是否有等效于 Strings.Format 方法的 VB.Net?

  • 1

有正在移植到 C# 的旧 VB.Net 代码。在此过程中移植Strings.Format时出现问题。
该代码使用
命名的日期时间格式、
命名的数字格式和
用户定义的字符串格式
(我仍然不明白为什么在 Strings.Format 文档页面上没有关于命名格式的所有信息)。

问题是上述格式存储在需要向后兼容的二进制配置文件中。比如有这样一个VB方法:

Public Function StringConvert(ByVal sValue As String, ByVal sFormatString As String) As String

    Dim RetWert As String
    Dim neuWert As String = Trim(sValue)
    Dim format As String = Trim(sFormatString)

    If format = "String" Then
        RetWert = neuWert
    ElseIf format = "General Date" Or
      format = "Long Date" Or
      format = "Short Date" Or
      format = "Medium Date" Or
      format = "Long Time" Or
      format = "Medium Time" Or
      format = "Short Time" Then
        If IsDate(sValue) Then
            RetWert = Format(CDate(neuWert), format)
        Else
            RetWert = ""
        End If
    ElseIf format = "General Number" Or
      format = "Currency" Or
      format = "Fixed" Or
      format = "Standard" Or
      format = "Percent" Or
      format = "Scientific" Then
        If IsNumeric(sValue) Then
            RetWert = Format(CDbl(neuWert), format)
        Else
            RetWert = ""
        End If
    ElseIf format = "Yes/No" Or
      format = "True/False" Or
      format = "On/Off" Then
        If IsNumeric(sValue) Then
            RetWert = Format(CBool(neuWert), format)
        Else
            RetWert = ""
        End If
    Else
        If InStr(format, "@") > 0 Or
           InStr(format, "&") > 0 Or
           InStr(format, "<") > 0 Or
           InStr(format, ">") > 0 Or
           InStr(format, "!") > 0 Then
            RetWert = Format(neuWert, format)
        ElseIf InStr(format, "c") > 0 Or InStr(format, "y") > 0 Or
               InStr(format, "d") > 0 Or InStr(format, "h") > 0 Or
               InStr(format, "w") > 0 Or InStr(format, "s") > 0 Or
               InStr(format, "m") > 0 Or InStr(format, "t") > 0 Or
               InStr(format, "q") > 0 Or InStr(format, "+") > 0 Then
            If IsNumeric(sValue) Then
                RetWert = Format(CDate(neuWert), format)
            Else
                RetWert = ""
            End If
        ElseIf InStr(format, " ") > 0 Or InStr(format, "%") > 0 Or
               InStr(format, "0") > 0 Or InStr(format, "-") > 0 Or
               InStr(format, "#") > 0 Or InStr(format, "E") > 0 Or
               InStr(format, ".") > 0 Or InStr(format, "e") > 0 Or
               InStr(format, ",") > 0 Or InStr(format, "+") > 0 Then
            If IsNumeric(sValue) Then
                RetWert = Format(CDbl(neuWert), format)
            Else
                RetWert = ""
            End If
        Else
            RetWert = CStr(neuWert)
        End If
    End If

    StringConvert = RetWert

End Function

我尝试为 DateTime 格式创建自己的IFormatProvider,但它只是转换字符串日期格式的字符(在下面的示例中是hand t)。当然,您可以导入 Microsoft.VisualBasic 命名空间并进一步使用该方法,但是(据我了解)这种方法不适用于 .Net Core,这很关键。

C# 中是否有等效于 Strings.Format 的方法?也许有一些库(.Net Standard)?您认为解决此问题的最佳方法是什么?

你可以在这里玩。

public class VBDateTimeFormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        return formatType == typeof(ICustomFormatter)
            ? this : null;
    }

    private readonly Dictionary<string, string> _map = new Dictionary<string, string>()
    {
        {"General Date", "G"},
        {"Long Date", "D"},
        {"Short Date", "d"},
        {"Medium Date", "D"},
        {"Long Time", "T"},
        {"Medium Time", "T"},
        {"Short Time", "t"}
    };

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        format = format.Trim();
        return _map.ContainsKey(format)
            ? DateTime.Parse(arg.ToString()).ToString(_map[format], CultureInfo.CurrentCulture)
            : string.Empty;
    }
}
// var dt = new DateTime(2020, 1, 1).ToString();
// Console.WriteLine(DateTime.Parse(dt).ToString(format, new VBDateTimeFormatProvider()));
// выводит: "S12orA DaAe"
c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-01-10 22:21:25 +0000 UTC

为什么在使用三元运算符创建简写谓词时不能使用条件逻辑运算符?

  • 1

我遇到了奇怪的行为:使用三元运算符创建谓词时,不能使用简写的条件逻辑运算符。发生编译器错误CS0173。也许代码会更好地解释它的含义。

public class Account {
  public bool IsDeleted { get; set; }
  public bool IsActive { get; set; }
}

// Так можно,
Predicate<Account> predicate = x => x.IsActive && !x.IsDeleted;

// а так нет,
Predicate<Account> predicate = onlyDeleted
  ? x => x.IsDeleted
  : x => x.IsActive && !x.IsDeleted;
// Ошибка CS0173
// Не удается определить тип условного выражения,
// так как неявного преобразования между
// "лямбда-выражение" и "лямбда-выражение" не существует.

// но так тоже можно.
Predicate<Account> predicate = onlyDeleted
  ? x => x.IsDeleted
  : new Predicate<Account>(x => x.IsActive && !x.IsDeleted);

使用 Visual Studio 2019 版本 16.4.2。


对为什么会发生这种情况感兴趣?也许还有其他选择?


现在(在 C# 9 中)它可以工作了。

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-01-08 18:28:00 +0000 UTC

格式化输出版本

  • 0

有一个版本实例需要转换为特定的文本格式。例如 Version12.3.4.0应该被强制转换为12.03.04.00. 目前我正在这样做:

public static string ToD2Format(this Version version)
{
    return version.Major.ToString("D2") + "."
        + version.Minor.ToString("D2") + "."
        + version.Build.ToString("D2") + "."
        + version.Revision.ToString("D2");
}

但碰巧代码库的不同部分使用不同的格式。因此,问题出现了:是否可以以任何方式(理想地优雅)设置字符串格式(例如,与复合格式相同)?

// вместо version.ToD2Format();
version.FormatTo("{0}.{1:D2}.{2:D2}.{3:D2}");

相关链接

  • 版本类
  • 自定义数字格式字符串
  • 复合格式
c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-10-18 19:09:01 +0000 UTC

如何以编程方式从表单中获取所有元素?

  • 0

我面临着获取表单中所有元素的任务,包括菜单和状态栏以及其他具有Text. 由于每个控件都有一个Controls属性(和窗体,分别),我可以使用以下代码来获取窗体的所有控件及其子控件:

public static IEnumerable<Control> GetControls(Control control)
{
    foreach (Control childControl in control.Controls)
    {
        foreach (Control grandChild in GetControls(childControl))
        {
            yield return grandChild;
        }
        yield return childControl;
    }
}

问题是菜单没有 Controls 属性,您必须使用Items属性来访问子元素。目前,我没有找到其他任何东西,如何检查类型。是否有可能以某种方式统一访问所有表单元素,包括子元素?

c#
  • 2 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-10-15 18:53:19 +0000 UTC

如何通过地址获取对象属性的值类型?[复制]

  • 1
这个问题已经在这里得到了回答:
如何通过地址获取对象属性的值?[重复] (1 个回答)
2年前关闭。

有一个对象实例和一个字符串,其中包含对象属性的“地址”的文本表示。例如:

public class Person {
  public string Name { get; set; }
  public DateTime BirthDate { get; set; }
  public Address BirthPlace { get; set; }
}
public class Address {
  public string Country { get; set; }
  public string City { get; set; }
  public string Street { get; set; }
  public string Nr { get; set; }
}

如何使用其“地址”获取属性值类型?
例如像这样:BirthPlace.Country?

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-10-01 16:38:28 +0000 UTC

服务和等级的区别

  • 2

与一位同事讨论了应该考虑什么服务和什么类。经过短暂的思考,我们得出的结论是,服务很可能是一个具有依赖关系并服务于重复性任务的类,但我们自己并不喜欢这种表述,因为它在很多方面也适合普通的静态帮助类。

服务和类之间的根本区别是什么?通过什么迹象我们可以说这不再是一个类,而是一个服务?我们可以通过什么迹象说这不是服务,而是课程?

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-09-12 20:51:38 +0000 UTC

可逆许可证密钥加密

  • 0

有一种算法可以为程序的离线激活生成许可证密钥。这意味着许可证信息直接编码在密钥中。要生成许可证密钥,需要使用应用程序的名称和版本,以及许可证所有者的姓名。几乎所有的代码都是从 Internet 上的各种来源收集的,并且在某种程度上适应了我的任务。我该怎么做和做什么:

许可证密钥生成

  1. 我使用程序的名称和版本创建了一个“盐”;
  2. 使用许可证所有者的名称作为解密许可证密钥的密码;
  3. 我使用先前创建的“salt”和密码创建 Rijndale - 许可证的所有者;
  4. 我将许可证信息加密为编码字节数组;
  5. 我将使用BASE36将生成的字节数组转换为人类可读的形式;

许可证解密

  1. 在程序方面,使用反射,我得到程序的名称和版本,以及许可证所有者;
  2. 根据收到的信息,我形成一个“盐”和一个密码;
  3. 我从BASE36格式的许可证密钥中取回一组编码字节;
  4. 使用之前创建的“salt”和密码创建 Rijndale ;
  5. 我将编码字节数组解码回许可证信息;

问题是我只能用这种方法加密长度在 16 到 31 个字符之间的字符串。如何针对不同长度的字符串修改现有代码?

PS:您可以在此处使用代码“玩耍” 。

BASE36 类

using System;
using System.Text;

namespace ConsoleApp1
{
    public static class BASE36
    {
        private const string _charList = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private static readonly char[] _charArray = _charList.ToCharArray();

        public static long Decode(string input)
        {
            long _result = 0;
            double _pow = 0;
            for (int _i = input.Length - 1; _i >= 0; _i--)
            {
                char _c = input[_i];
                int pos = _charList.IndexOf(_c);
                if (pos > -1)
                {
                    _result += pos * (long)Math.Pow(_charList.Length, _pow);
                }
                else
                {
                    return -1;
                }

                _pow++;
            }
            return _result;
        }

        public static string Encode(ulong input)
        {
            var _sb = new StringBuilder();
            do
            {
                _sb.Append(_charArray[input % (ulong)_charList.Length]);
                input /= (ulong)_charList.Length;
            } while (input != 0);

            return Reverse(_sb.ToString());
        }

        private static string Reverse(string s)
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }
    }
}

节目班

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string saltString = GetSaltString("Blechexport", "15");
            byte[] salt = Encoding.UTF8.GetBytes(saltString);
            string pwd = "J.Doe";
            string licInfo = $"[0,{new DateTime(2019, 11, 30).Ticks},10]";
            var bytes = Encoding.UTF8.GetBytes(licInfo);
            var seconds = new DateTime(2019, 12, 31).Ticks / 10000000;
            string[] testDatas = new string[]{
                $"[0,{seconds},1]",
                $"[1,{seconds},10]",
                $"[2,{seconds},10,10]",
                $"[3,{seconds},10,10,10]",
                $"[3,{seconds},10,10,10,10]",
                $"[3,{seconds},10,10,10,10,10]"
                // throws System.Security.Cryptography.CryptographicException
                // ,$"[3,{seconds},10,10,10,10,10,10]"
            };
            foreach (string testData in testDatas)
            {
                TestLic(pwd, salt, testData);
            }
            Console.ReadKey();
        }

        static void TestLic(string pwd, byte[] salt, string phrase)
        {
            var bytes = Encoding.UTF8.GetBytes(phrase);
            Console.WriteLine("------------------------------------------");
            Console.WriteLine($"phrase: {phrase} ({phrase.Length} symbols)");
            string licKey;
            using (var rijndael = InitSymmetric(Rijndael.Create(), pwd, salt, 256))
            {
                byte[] encryptedBytes = Transform(bytes, rijndael.CreateEncryptor);
                licKey = GenerateUID(encryptedBytes);
                Console.WriteLine($"encrypted bytes: {BitConverter.ToString(encryptedBytes)}");
                Console.WriteLine($"license key: {licKey}");
                Console.WriteLine($"key length: {licKey.Length}");
            }

            using (var rijndael = InitSymmetric(Rijndael.Create(), pwd, salt, 256))
            {
                byte[] uidBytes = GetUIDInBytes(licKey);
                byte[] decryptedBytes = Transform(uidBytes, rijndael.CreateDecryptor);
                Console.WriteLine($"decrypted bytes: {BitConverter.ToString(decryptedBytes)}");
                string decryptedText = Encoding.UTF8.GetString(decryptedBytes);
                Console.WriteLine("decryptedText: {0}", decryptedText);
            }
            Console.WriteLine("------------------------------------------");
        }

        static string GetSaltString(string programmName, string programmVersion)
        {
            return $"{programmName}.{programmVersion}";
        }

        static string GenerateUID(byte[] bytes)
        {
            //Convert checksum into 4 ulong parts and use BASE36 to encode both
            string _part1Id = BASE36.Encode(BitConverter.ToUInt64(bytes, 0));
            string _part2Id = BASE36.Encode(BitConverter.ToUInt64(bytes, 8));
            string _part3Id = BASE36.Encode(BitConverter.ToUInt64(bytes, 16));
            string _part4Id = BASE36.Encode(BitConverter.ToUInt64(bytes, 24));
            //Concat these 4 part into one string
            return string.Format("{0}-{1}-{2}-{3}", _part1Id, _part2Id, _part3Id, _part4Id);
        }

        static byte[] GetUIDInBytes(string UID)
        {
            //Split 4 part Id into 4 ulong
            string[] _ids = UID.Split('-');
            //Combine 4 part Id into one byte array
            byte[] _value = new byte[32];
            Buffer.BlockCopy(BitConverter.GetBytes(BASE36.Decode(_ids[0])), 0, _value, 0, 8);
            Buffer.BlockCopy(BitConverter.GetBytes(BASE36.Decode(_ids[1])), 0, _value, 8, 8);
            Buffer.BlockCopy(BitConverter.GetBytes(BASE36.Decode(_ids[2])), 0, _value, 16, 8);
            Buffer.BlockCopy(BitConverter.GetBytes(BASE36.Decode(_ids[3])), 0, _value, 24, 8);
            return _value;
        }

        static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (string.IsNullOrEmpty(plainText))
            {
                throw new ArgumentNullException(nameof(plainText));
            }
            if (Key == null || Key.Length == 0)
            {
                throw new ArgumentNullException(nameof(Key));
            }
            if (IV == null || IV.Length == 0)
            {
                throw new ArgumentNullException(nameof(IV));
            }
            byte[] encrypted;
            // Create an AesManaged object
            // with the specified key and IV.
            using (AesManaged aesAlg = new AesManaged())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;
                // Create an encryptor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }

                        encrypted = msEncrypt.ToArray();
                    }
                }
            }
            // Return the encrypted bytes from the memory stream.
            return encrypted;
        }

        static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
            {
                throw new ArgumentNullException(nameof(cipherText));
            }
            if (Key == null || Key.Length <= 0)
            {
                throw new ArgumentNullException(nameof(Key));
            }
            if (IV == null || IV.Length <= 0)
            {
                throw new ArgumentNullException(nameof(IV));
            }
            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;
            // Create an AesManaged object
            // with the specified key and IV.
            using (AesManaged aesAlg = new AesManaged())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;
                // Create a decryptor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
            return plaintext;
        }

        static SymmetricAlgorithm InitSymmetric(SymmetricAlgorithm algorithm, string password, byte[] salt, int keyBitLength)
        {
            const int Iterations = 234;
            using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations))
            {
                if (!algorithm.ValidKeySize(keyBitLength))
                {
                    throw new InvalidOperationException("Invalid size key");
                }
                algorithm.Key = rfc2898DeriveBytes.GetBytes(keyBitLength / 8);
                algorithm.IV = rfc2898DeriveBytes.GetBytes(algorithm.BlockSize / 8);
                return algorithm;
            }
        }

        static byte[] Transform(byte[] bytes, Func<ICryptoTransform> selectCryptoTransform)
        {
            using (var memoryStream = new MemoryStream())
            {
                using (var cryptoStream = new CryptoStream(memoryStream, selectCryptoTransform(), CryptoStreamMode.Write))
                {
                    cryptoStream.Write(bytes, 0, bytes.Length);
                }
                return memoryStream.ToArray();
            }
        }
    }
}
c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-09-11 03:50:54 +0000 UTC

不同的程序集是否可以或应该具有相同的 GUID?

  • 2

有一个旧的 VB.Net 项目,它决定用 C# 恢复和重写。为方便起见,决定在同一解决方案中添加一个新项目。新项目在生成项目时会收到​​一个 GUID,这当然与旧解决方案中使用的 GUID 不同。该项目未对 COM ( [assembly: ComVisible(false)]) 开放,并且未在全局程序集缓存 (GAC) 中注册。

如果您打算完全重写应用程序并仅在将来使用它,构建 GUID 是否应该与旧的相同?在不同的程序集中使用相同的 GUID 会有什么后果?

c#
  • 1 个回答
  • 10 Views
Martin Hope
XelaNimed
Asked: 2020-08-30 20:17:16 +0000 UTC

如何通过分组序号更新列?

  • 0

如何构建查询以按分组中的序号更新列?例如,有下表:

+----+------+------+----------+
| Id | Col1 | Col2 |   Col3   |
+----+------+------+----------+
|  1 | aaa  | bbb  | abcdef   |
|  2 | ccc  | ddd  | ghijklmn |
|  3 | eee  | fff  | abcdef   |
|  4 | ggg  | hhh  | ghijklmn |
|  5 | iii  | jjj  | ghijklmn |
|  6 | kkk  | lll  | abcdef   |
+----+------+------+----------+

可以看到,Col3列中有重复值。如何构建一个 SQL 查询来更新表,以便在其执行后,组的序号在列中,Col1还是Col2无关紧要?排序顺序无关紧要。目标是为每个组设置一个唯一的数字。

+----+------+------+----------+
| Id | Col1 | Col2 |   Col3   |
+----+------+------+----------+
|  1 | aaa  | 1    | abcdef   |
|  2 | ccc  | 2    | ghijklmn |
|  3 | eee  | 1    | abcdef   |
|  4 | ggg  | 2    | ghijklmn |
|  5 | iii  | 2    | ghijklmn |
|  6 | kkk  | 1    | abcdef   |
+----+------+------+----------+
sql
  • 2 个回答
  • 10 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