博客 (168)

Pomelo.EntityFrameworkCore.MySql 升级到 7.0 后出现:

System.InvalidOperationException:“The 'sbyte' property could not be mapped to the database type 'tinyint(1)' because the database provider does not support mapping 'sbyte' properties to 'tinyint(1)' columns. Consider mapping to a different database type or converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.”

对比 6.0 生成的 DbContext.cs 发现缺少了 UseLoggerFactory,按旧版修改即可。


找到 OnConfiguring 方法,上方插入:

public static readonly LoggerFactory MyLoggerFactory = new LoggerFactory(new[] {
    new DebugLoggerProvider()
});

在 OnConfiguring 方法中将:

optionsBuilder.UseMySql("连接字符串");

改为:

optionsBuilder.UseLoggerFactory(MyLoggerFactory).UseMySql("连接字符串");


xoyozo 2 年前
1,514

错误 BLAZOR102     The scoped css file was defined but no associated razor component or view was found for it.

错误 BLAZOR106 The JS module file was defined but no associated razor component or view was found for it.

解决方法:将相关文件从项目中排除,再包括到项目中即可正常生成。

若仍报错,备份这些文件,删除并新建文件,复制代码进去尝试生成。

若仍报错,通过注释代码的方式排查问题原因。

xoyozo 2 年前
1,951

bundleconfig.json 有格式错误

xoyozo 2 年前
1,346

LigerShark.WebOptimizer.CoreBuildBundlerMinifier
特点

在运行时捆绑和缩小 CSS 和 JavaScript 文件

具有完整的服务器端和客户端缓存,以确保高性能

可禁用缩小

支持使用通配模式

标记帮助程序与缓存破坏

支持内联

支持 SCSS

将 CSS、JavaScript 或 HTML 文件捆绑到单个输出文件中

保存源文件会自动触发重新捆绑

支持通配模式

支持 CI 方案的 MSBuild 支持

缩小单个或捆绑的 CSS、JavaScript 和 HTML 文件

每种语言的缩小选项是可定制的

打开生成的文件时显示水印

任务运行程序资源管理器集成

命令行支持

快捷更新解决方案中所有捆绑包

禁止生成输出文件

转换为 Gulp

注入(Program.cs)

services.AddWebOptimizer();

app.UseWebOptimizer();


指定捆绑的项目在运行时自动缩小 css 和 js,也可以在 AddWebOptimizer 中自定义。默认情况下,生成的文件不会保存到磁盘,而是保存在缓存中。手动编辑 bundleconfig.json 文件来指定需要合并和缩小的文件
功能配置
{
  "webOptimizer": {
    // 确定是否应设置 HTTP 标头以及是否应支持条件 GET (304) 请求。在开发模式下禁用此功能可能会有所帮助。cache-control
    "enableCaching": true,
    // 确定是否用于缓存。在开发模式下禁用可能会有所帮助。IMemoryCache
    "enableMemoryCache": true,
    // 确定管道资产是否缓存到磁盘。这可以通过从磁盘加载 pipline 资产而不是重新执行管道来加快应用程序重新启动的速度。在开发模式下禁用可能会有所帮助。
    "enableDiskCache": true,
    // 设置资产将存储的目录 ifistrue。必须为读/写。enableDiskCache
    "cacheDirectory": "/var/temp/weboptimizercache",
    // 确定元素是否应指向捆绑路径或应为每个源文件创建引用。这在开发模式下禁用很有帮助。
    "enableTagHelperBundling": true,
    // 是一个绝对 URL,如果存在,它会自动为页面上的任何脚本、样式表或媒体文件添加前缀。注册标记帮助程序后,标记帮助程序会自动添加前缀。在此处查看如何注册标记帮助程序。
    "cdnUrl": "https://my-cdn.com/",
    // 确定捆绑包的源文件中没有内容时的行为,默认情况下,请求捆绑包时将引发 404 异常,设置为 true 以获取包含空内容的捆绑包。
    "allowEmptyBundle": false
  }
}


在 bundleconfig.json 捆绑时设置

[
  {
    "outputFileName": "output/bundle.css",
    "inputFiles": [
      "css/lib/**/*.css", // globbing patterns are supported
      "css/input/site.css"
    ],
    "minify": {
        "enabled": true,
        "commentMode": "all"
    }
  },
  {
    "outputFileName": "output/all.js",
    "inputFiles": [
      "js/*.js",
      "!js/ignore.js" // start with a ! to exclude files
    ]
  },
  {
    "outputFileName": "output/app.js",
    "inputFiles": [
      "input/main.js",
      "input/core/*.js" // all .js files in input/core/
    ]
  }
]


热重载(在开发模式中保存文件自动更新浏览器效果)
VS 安装扩展,方法:菜单 - 扩展 - 管理扩展 - 联机 搜索“Bundler & Minifier
其它资料
ASP.NET 官方文档


xoyozo 2 年前
1,950

原生判断

window.addEventListener('scroll', scroll)

function scroll() {
      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
      const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
      
      if (scrollTop === 0) {
        console.log('滚动到顶了');
      }
      if (scrollTop + clientHeight >= scrollHeight - 100) {
        console.log('滚动到底了');
      }
}

window.removeEventListener('scroll', scroll) // 移除滚动事件

scrollTop:文档在可视区上沿的位置距离文档顶部的距离

clientHeight:可视区的高度

scrollHeight:文档总高度

100:用于在滚动到底部之前提前加载内容(如瀑布流),提高用户体验,请自行修改数值(建议不小于 2 像素,以规避在部分浏览器上因获得值为小数时可能无法触发的问题)


jQuery 判断

window.addEventListener('scroll', scroll)

function scroll() {
    const doc_height = $(document).height();
    const scroll_top = $(document).scrollTop();
    const window_height = $(window).height();
    
    if (scroll_top === 0) {
      console.log('滚动到顶了');
    } else if (scroll_top + window_height >= doc_height - 100) {
      console.log('滚动到底了');
    }
}


xoyozo 2 年前
1,599
操作系统
版本发布时间支持设备
macOS Sequoia152024年6月

iMac (2019 年及后续机型)

Mac Pro (2019 年及后续机型)

iMac Pro (2017 年及后续机型)

Mac Studio (2022 年及后续机型)

MacBook Air (2020 年及后续机型)

Mac mini (2018 年及后续机型)

MacBook Pro (2018 年及后续机型)

macOS Sonoma142023年秋

iMac (2019 年及后续机型)

Mac Pro (2019 年及后续机型)

iMac Pro (2017 年机型)

Mac Studio (2022 年及后续机型)

MacBook Air (2018 年及后续机型)

Mac mini (2018 年及后续机型)

MacBook Pro (2018 年及后续机型)

macOS Ventura132022年10月

iMac (2017 年及后续机型)

Mac Pro (2019 年及后续机型)

iMac Pro (2017 年机型)

Mac Studio (2022 年机型)

MacBook Air (2018 年及后续机型)

Mac mini (2018 年及后续机型)

MacBook Pro (2017 年及后续机型)

MacBook (2017 年机型)

macOS Monterey122021年6月8日

iMac (2015 年末及后续机型)

Mac Pro (2013 年末及后续机型)

iMac Pro (2017 年及后续机型)

Mac mini (2014 年末及后续机型)

MacBook Air (2015 年初及后续机型)

MacBook (2016 年初及后续机型)

MacBook Pro (2015 年初及后续机型)

https://support.apple.com/zh-cn/HT212551

macOS Big Sur112020年6月23日

MacBook (2015 年或后续机型)

MacBook Air (2013 年或后续机型)

MacBook Pro (2013 年后期或后续机型)

Mac mini (2014 年或后续机型)

iMac (2014 年或后续机型)

iMac Pro (2017 年或后续机型)

Mac Pro (2013 年或后续机型)

https://support.apple.com/zh-cn/HT211238

https://support.apple.com/kb/sp833?locale=zh_CN

macOS Catalina10.152019年10月8日

MacBook (2015 年前期或之后的机型)

MacBook Air (2012 年中期或之后的机型)

MacBook Pro (2012 年中期或之后的机型)

Mac mini (2012 年后期或之后的机型)

iMac (2012 年后期或之后的机型)

iMac Pro (2017 年)

Mac Pro (2013 年后期或之后的机型)

https://support.apple.com/zh-cn/HT210222

https://support.apple.com/kb/sp803?locale=zh_CN

macOS Mojave10.142018年6月5日

MacBook (2015 年前期或之后的机型)

MacBook Air (2012 年中期或之后的机型)

MacBook Pro (2012 年中期或之后的机型)

Mac mini (2012 年后期或之后的机型)

iMac (2012 年后期或之后的机型)

iMac Pro (2017 年)

Mac Pro (2013 年后期的机型,以及支持特定 Metal 技术图形卡的 2010 年中期和 2012 年中期的机型)

https://support.apple.com/kb/SP777?locale=zh_CN

macOS High Sierra10.132017年6月5日

MacBook (2009 年后期或之后的机型)

MacBook Pro (2010 年中期或之后的机型)

MacBook Air (2010 年后期或之后的机型)

Mac mini (2010 年中期或之后的机型)

iMac (2009 年后期或之后的机型)

Mac Pro (2010 年中期或之后的机型)

https://support.apple.com/kb/SP765?locale=zh_CN

macOS Sierra10.122016年9月20日

MacBook (2009 年后期或之后的机型)

MacBook Pro (2010 年中期或之后的机型)

MacBook Air (2010 年后期或之后的机型)

Mac mini (2010 年中期或之后的机型)

iMac (2009 年后期或之后的机型)

Mac Pro (2010 年中期或之后的机型)

https://support.apple.com/kb/SP742?locale=zh_CN

OS X El Capitan10.112015年9月29日

MacBook (2015 年前期的机型)

MacBook (2008 年后期的铝金属机型以及 2009 年前期或之后的机型)

MacBook Pro (2007 年中期/后期或之后的机型)

MacBook Air (2008 年后期或之后的机型)

Mac mini (2009 年前期或之后的机型)

iMac (2007 年中期或之后的机型)

Mac Pro (2008 年前期或之后的机型)

Xserve (2009 年前期的机型)

https://support.apple.com/kb/SP728?locale=zh_CN

OS X Yosemite10.102014年10月17日

https://support.apple.com/kb/SP711?locale=zh_CN

OS X Mavericks10.92013年10月23日

iMac (2007 年中期或之后的机型)

MacBook (2008 年后期的铝金属机型、2009 年前期或之后的机型)

MacBook Pro (2007 年中后期或之后的机型)

Xserve (2009 年前期)

MacBook Air (2008 年后期或之后的机型)

Mac mini (2009 年前期或之后的机型)

Mac Pro (2008 年前期或之后的机型)

https://support.apple.com/kb/SP702?locale=zh_CN

OS X Mountain Lion10.82012年7月25日

iMac (2007 年中期或之后的机型)

MacBook (2008 年后期的铝制机型、2009 年前期或之后的机型)

MacBookPro(2007 年中期/后期或之后的机型)

Xserve (2009 年前期)

MacBook Air (2008 年后期或之后的机型)

Mac mini (2009 年前期或之后的机型)

Mac Pro (2008 年前期或之后的机型)

https://support.apple.com/kb/SP654?locale=zh_CN

OS X Lion10.72010年10月20日

https://support.apple.com/kb/SP629?locale=zh_CN

OS X Snow Leopard10.62008年6月9日

https://support.apple.com/kb/SP575?locale=zh_CN

参考资料:

使用 Mac 随附的 Mac 操作系统或兼容的更新版本

xoyozo 2 年前
4,671

首先,禁止网站下所有 .php 等文件均不允许被访问到。

在 nginx 网站配置文件中,include enable-php-**.conf; 上方插入:

location ~ ^/.*\.(php|php5|py|sh|bash|out)$ { deny all; }

其中,^ 匹配开始,/.* 匹配所有目录和文件名,\.(php|php5|py|sh|bash|out) 匹配文件后缀名,$ 匹配结束。

即便如此,仍然忽略了 nginx 中 .php 文件名后加斜杠仍然能访问到的情况,譬如我们访问这个网址:

https://xoyozo.net/phpinfo.php/abc.html

nginx 仍然运行了 phpinfo.php,给了后门可趁之机,所以改进为:

location ~ ^/.*\.(php|php5|py|sh|bash|out)(/.*)?$ { deny all; }


Discuz! X3.4 需要写入权限的目录:

  • /自研目录/upload/

  • /config/

  • /data/

  • /uc_client/data/

  • /uc_server/data/

  • /source/plugin/

但,这些都不重要,我们已经禁止了所有目录的 .php 访问了。


第二步,解禁需要直接被访问到的文件路径。

Discuz! X3.4 根目录下的 .php 文件都是入口文件,需要能够被访问到:

/admin.php
/api.php
/connect.php
/forum.php
/group.php
/home.php
/index.php
/member.php
/misc.php
/plugin.php
/portal.php
/search.php

其它目录中需要被直接访问到的文件:

/archiver/index.php
/m/index.php
/uc_server/admin.php
/uc_server/avatar.php
/uc_server/index.php

部分插件文件需要能够被直接访问到:

/source/plugin/magmobileapi/magmobileapi.php
/source/plugin/smstong/accountinfo.php
/source/plugin/smstong/checkenv.php

另外如果有自建目录需要有 .php 访问权限,那么也需要在此处加白,本文以 /_/ 目录为例

最终拼成:工具

location ~ ^(?:(?!(/admin\.php|/api\.php|/connect\.php|/forum\.php|/group\.php|/home\.php|/index\.php|/member\.php|/misc\.php|/plugin\.php|/portal\.php|/search\.php|/archiver/index\.php|/m/index\.php|/uc_server/admin\.php|/uc_server/avatar\.php|/uc_server/index\.php|/source/plugin/magmobileapi/magmobileapi\.php|/source/plugin/smstong/accountinfo\.php|/source/plugin/smstong/checkenv\.php|/_/.*\.php))/.*\.(php|php5|py|sh|bash|out)(/.*)?)$ { deny all; }

这里用到正则表达式中的“不捕获”和“负向零宽断言”语法,格式为:

^(?:(?!(允许的目录或文件A|允许的目录或文件B))禁止的目录和文件)$

值得注意的是,此句负向零宽断言中的匹配内容是匹配前缀的,也就是说

https://xoyozo.net/index.php
https://xoyozo.net/index.php/abc.html

都可以访问到,而

https://xoyozo.net/forbidden.php
https://xoyozo.net/forbidden.php/abc.html

都访问不到,这是符合需求的。

如果自建目录 /_/ 下有写入需求,单独禁止即可,以 /_/upload/ 为例:

location ~ ^/_/upload/.*\.(php|php5|py|sh|bash|out)(/.*)?$ { deny all; }


ThinkPHP 网站有统一的访问入口,可按本文方法配置访问权限。


特别注意:上面的代码必须加在 PHP 引用配置(include enable-php-**.conf;)的上方才有效。


附:一键生成 nginx 访问控制 location URI { } 语句工具

xoyozo 2 年前
2,986

外星人笔记本电脑键盘突然失灵(我的是 m15 R6),尝试过重启电脑、长按电源键(强制关机、切换电脑性能)、卸载键盘驱动、BIOS 恢复默认设置都没有效果。多次尝试后恢复正常,总结经验:

办法一:关机、拔掉电源、插上电源、再开机,就能恢复正常。

办法二:长按电源键直到关机成功,长按电源键直至开机完成。

若无效,强制关机、插拔电源,多试几次。

总之,这电脑不用的时候尽量关机,直接合上盖子会出现自动苏醒、键盘失灵等一系列问题。


2023年9月补充,最近发现直接合上盖子没有出现自动苏醒,先睡眠再拔电源也没有出现苏醒,可能与我经常在 Alienware Update 和 SupportAssist 中更新驱动和固件有关。

2024年6月补充,出现键盘失灵可以试试合上盖子再打开,大概率能恢复。

xoyozo 2 年前
8,405

本文使用 ASP.NET 6 版本 Senparc.Weixin.Sample.MP 示例项目改造。


第一步 注册多公众号

方法一:打开 appsettings.json 文件,在 SenparcWeixinSetting 节点内添加数组节点 Items,该对象类型同 SenparcWeixinSetting。

//Senparc.Weixin SDK 设置
"SenparcWeixinSetting": {
  "IsDebug": true,
  "Token": "",
  "EncodingAESKey": "",
  "WeixinAppId": "",
  "WeixinAppSecret": "",
  "Items": [
    {
      "IsDebug": true,
      "Token": "a",
      "EncodingAESKey": "a",
      "WeixinAppId": "a",
      "WeixinAppSecret": "a"
    },
    {
      "IsDebug": true,
      "Token": "b",
      "EncodingAESKey": "b",
      "WeixinAppId": "b",
      "WeixinAppSecret": "b"
    }
  ]
}

方法二:修改 Program.cs 文件,在 UseSenparcWeixin 方法中注册多个公众号信息。

var registerService = app.UseSenparcWeixin(app.Environment,
    null /* 不为 null 则覆盖 appsettings  中的 SenparcSetting 配置*/,
    null /* 不为 null 则覆盖 appsettings  中的 SenparcWeixinSetting 配置*/,
    register => { /* CO2NET 全局配置 */ },
    (register, weixinSetting) =>
    {
        //注册公众号信息(可以执行多次,注册多个公众号)
        //register.RegisterMpAccount(weixinSetting, "【盛派网络小助手】公众号");
        foreach (var mp in 从数据库或配置文件中获取的公众号列表)
        {
            register.RegisterMpAccount(new SenparcWeixinSetting
            {
                //IsDebug = true,
                WeixinAppId = mp.AppId,
                WeixinAppSecret = mp.AppSecret,
                Token = mp.Token,
                EncodingAESKey = mp.EncodingAeskey,
            }, mp.Name);
        }
    });

完成后,我们可以从 Config.SenparcWeixinSetting.Items 获取这些信息。


第二步 接入验证与消息处理

打开 WeixinController 控制器,将构造函数改写为:

public WeixinController(IHttpContextAccessor httpContextAccessor)
{
    AppId = httpContextAccessor.HttpContext!.Request.Query["appId"];
    var MpSetting = Services.MPService.MpSettingByAppId(AppId);
    Token = MpSetting.Token;
    EncodingAESKey = MpSetting.EncodingAESKey;
}

示例中 Services.MPService.MpSettingByAppId() 方法实现从 Config.SenparcWeixinSetting.Items 返回指定 appId 的公众号信息。

为使 IHttpContextAccessor 注入生效,打开 Program.cs,在行

builder.Services.AddControllersWithViews();

下方插入

builder.Services.AddHttpContextAccessor();

这样,我们就可以在构造函数中直接获取地址栏中的 appId 参数,找到对应的公众号进行消息处理。


第三步 消息自动回复中的 AppId

打开 CustomMessageHandler.cs,将 

private string appId = Config.SenparcWeixinSetting.MpSetting.WeixinAppId;
private string appSecret = Config.SenparcWeixinSetting.MpSetting.WeixinAppSecret;

替换为:

private string appId = null!;
private string appSecret = null!;

并在构造函数中插入

appId = postModel.AppId;
appSecret = Services.MPService.MpSettingByAppId(postModel.AppId).WeixinAppSecret;

这样,本页中使用的 appId / appSecret 会从 postModel 中获取,而非默认公众号。postModel 已在 WeixinController 中赋值当前的 appId。

改造后,我们可以在 OnTextRequestAsync() 等处理消息的方法中可以判断 appId 来处理不同的消息。


第四步 其它功能和接口

其它功能和接口均可用指定的 AppId 和对应的 AppSecret 进行调用。

xoyozo 2 年前
3,107

在 Notepad++ 工具菜单上选择:插件 - 插件管理,搜索“HEX-Editor”,选中并点击安装。

image.png

然后点击:插件 - HEX-Editor - View In HEX,就可以查看了。

image.png

xoyozo 2 年前
5,081