异常提示:
HTTP Error 500.31 - ANCM Failed to Find Native Dependencies
Common solutions to this issue:
The specified version of Microsoft.NetCore.App or Microsoft.AspNetCore.App was not found.
Troubleshooting steps:
-
Check the system event log for error messages
-
Enable logging the application process' stdout messages
-
Attach a debugger to the application process and inspect
For more information visit: https://go.microsoft.com/fwlink/?LinkID=2028526
解决方法:
安装对应版本(或最新版本)的 ASP.NET Core Runtime,前往下载:https://dotnet.microsoft.com/download
小米电视 5 | 小米电视 5 Pro | |
亮点 | 全面屏、超薄金属机身、小爱同学、远场语音、PatchWall、4K、四单元喇叭、3GB+32GB | 量子点、MEMC运动补偿、4K+HDR10+、全面屏、小爱同学、远场语音、PatchWall、4GB+64GB |
分辨率 | 3840x2160(4K) | |
背光 | 侧入式 | |
可视角度 | 178° | |
刷新率 | 60Hz | |
广色域 | NTSC 85% | NTSC 108% |
CPU | Cortex A55 | |
GPU | Mali-G31 MP2 | |
内存 | 3GB | 4GB |
闪存 | 32GB | 64GB |
解码能力 | 8K 视频解码 | |
无线 | 2.4GHz/5GHz、蓝牙、红外 | |
尺寸 | 55 英寸 长 1227mm 高 717.8mm 含脚架高 773.2mm 65 英寸 长 1445.9mm 高 831.4mm 含脚架高 898mm 75 英寸 长 1676.5mm 宽 973.3mm 含脚架高 1037.7mm | |
首发价格 | 55" ¥2999 65" ¥3999 75" ¥7999 | 55" ¥3699 65" ¥4999 75" ¥9999 |
首发价格(舍入) | 55" ¥3000 65" ¥4000 75" ¥8000 | 55" ¥3700 65" ¥5000 75" ¥10000 |
本文环境:CentOS 7、nginx 1.16、ASP.NET Core 3.0
安装 nginx,可以使用宝塔面板。
创建网站,保证网站静态页面能够正常访问。
必要时配置 SSL 证书。
安装 ASP.NET Core 运行时:
安装说明见:https://dotnet.microsoft.com/download,切换到 Linux,选择 Install .NET Core Runtime
选择操作系统,按页面说明安装即可。
发布一个 ASP.NET Core 项目到网站目录,运行应用程序:
dotnet 应用的程序集文件名.dll
必须先 cd 到项目所在目录再执行,否则“Content root path”不会指向网站根目录,从而导致无法访问静态文件。
观察到端口为 5000(默认),该 Url 用于下一步设置反向代理。
配置 nginx 反向代理:(使用宝塔面板时建议使用面板中提供的“反向代理”功能)
location / { proxy_pass http://localhost:5000; }
查看官方详细说明:使用 Nginx 在 Linux 上托管 ASP.NET Core
型号 | 传输速率 | 带宽 | 类型 | 相对于上一类的优势 |
一类线(CAT1) | - | - | 非屏蔽/屏蔽 | 传输语音 |
二类线(CAT2) | 4Mbps | 1MHz | 非屏蔽/屏蔽 | 可传输数据 |
三类线(CAT3) | 10Mbps | 16MHz | 非屏蔽/屏蔽 | 速度提升 |
四类线(CAT4) | 16Mbps | 20MHz | 非屏蔽/屏蔽 | 速度提升 |
五类线(CAT5) | 100Mbps | 100MHz | 非屏蔽/屏蔽 | 增加密度、绝缘材料 |
超五类线(CAT5e) | 1Gbps | 100MHz | 非屏蔽/屏蔽 | 衰减小、串扰少 |
六类线(CAT6) | 1Gbps | 1~250MHz | 非屏蔽/屏蔽 | 全双工,改善串扰及回波损耗 |
超六类线(CAT6e) | 1Gbps? 10Gbps? | 200~250 MHz | 非屏蔽/屏蔽 | 改善串扰、衰减、信噪比等 |
七类线(CAT7) | 10Gbps | 500MHz+ | 屏蔽 | 适应万兆位以太网技术 |
八类线(CAT8) | 25Gbps、40Gbps | 屏蔽 |
普通家庭装修布线建议上到千兆网络(2019年),至少选择六类网线。
本文介绍 ASP.NET 的 Swagger 部署,若您使用 ASP.NET Core 应用程序,请移步 ASP.NET Core Web API Swagger 官方文档:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore
安装
NuGet 中搜索安装 Swashbuckle,作者 Richard Morris
访问
http://您的域名/swagger
配置
显示描述
以将描述文件(xml)存放到项目的 bin 目录为例:
打开项目属性,切换到“生成”选项卡
在“配置”下拉框选择“所有配置”
更改“输出路径”为:bin\
勾选“XML 文档文件”:bin\******.xml,(默认以程序集名称命名)
打开文件:App_Start/SwaggerConfig.cs
取消注释:c.IncludeXmlComments(GetXmlCommentsPath());
添加方法:
public static string GetXmlCommentsPath() { return System.IO.Path.Combine( System.AppDomain.CurrentDomain.BaseDirectory, "bin", string.Format("{0}.xml", typeof(SwaggerConfig).Assembly.GetName().Name)); }
其中 Combine 方法的第 2 个参数是项目中存放 xml 描述文件的位置,第 3 个参数即以程序集名称作为文件名,与项目属性中配置一致。
如遇到以下错误,请检查第 2、3、4 步骤中的配置(Debug / Release)
500 : {"Message":"An error has occurred."} /swagger/docs/v1
使枚举类型按实际文本作为参数值(而非转成索引数字)
打开文件:App_Start/SwaggerConfig.cs
取消注释:c.DescribeAllEnumsAsStrings();
前言:
ChatGPT 给了 3 条建议:
在应用程序中正确释放数据库连接。确保在使用完数据库连接后,将其关闭并将其返回到连接池中。您可以使用 using 语句来确保连接在使用完毕后被正确释放。
调整连接池的大小。默认情况下,连接池的最大大小为 100。如果您的应用程序需要更多的连接,则可以增加连接池的大小。您可以在连接字符串中设置 Max Pool Size 属性来调整连接池的大小。
调整连接池的超时时间。默认情况下,连接池中的连接在 30 秒钟内未使用时将被关闭。如果您的应用程序需要更长的连接时间,则可以增加连接池的超时时间。您可以在连接字符串中设置 Connection Lifetime 属性来调整连接池的超时时间。
亲测有效,尤其是第 3 条,原因是 Connection Lifetime 的默认值是 0,即没有超时限制。
—— 2023.5
一般地,我们使用 EF 连接数据库前会先初始化一个数据库上下文:
dbEntities db = new dbEntities();
虽然 ASP.NET 会在查询完毕后自动关闭该连接,但是在什么情况下回收等都是不确定的,所以会导致 MySQL 中出现很多 Sleep 的连接(执行命令 SHOW FULL PROCESSLIST
可见),占用数据库的连接数,除非主动调用 Dispose():
db.Dispose();
官方建议的写法是使用 using
语法:
using (dbEntities db = new dbEntities())
{
}
using 会自动调用 Dispose()。这样对减少连接数是很有效的,但官方提示为了提高下一次连接的速度,并不会完全关闭所有连接。
C# 8 建议写法:
using dbEntities db = new dbEntities();
在实际项目中(该项目有 500+处数据库连接)测试结果,在不执行 Dispose() 时稳定为 140 个左右连接数,使用 using 或 Dispose() 后稳定变为 40 个左右。
如果不小心在 using 外部或 Dispose() 后再次对该上下文执行查询操作会出现异常:
无法完成该操作,因为 DbContext 已释放。
或
此 ObjectContext 实例已释放,不可再用于需要连接的操作。
所以要避免出现这种情况。这里还有一种另类的解决方法(不建议),根据上下文的特性,只要在 using 内查询一次(譬如视图中需要用到的导航属性,即外键关联的表),就可以在外部使用这个属性。
(建议)在 ASP.NET MVC 或 Web API 项目中,如果一个控制器中仅在 Action 外部定义一个 DbContext,那么,只要重写该控制器的 Dispose() 方法即可:
private dbEntities db = new dbEntities();
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
上下文使用 private 修饰即可。
如何查看 ASP 详细错误信息
解决办法:
打开 IIS,在相应网站的功能视图中双击“错误页”,在右侧“操作”栏中点击“编辑功能设置…”,将“错误响应”更改为“详细错误”。
在功能视图中双击“ASP”,展开“调试属性”,“将错误发送到浏览器”设为 True。记得在网站调试完成后还原此项设置。
若仍不显示,本地浏览器去掉了“显示 http 友好错误提示”选项。
在学习和使用 ASP.NET Web API 之前,最好先对 RESTful 有所了解。它是一种软件架构风格、设计风格,而不是标准。
推荐视频教程:https://www.imooc.com/learn/811
讲师:会飞的鱼Xia
需时:2小时25分
REST API 测试工具:
在 Chrome 网上应用店中搜索:Restlet Client
或网站 https://client.restlet.com
>>> 资源路径
SCHEME :// HOST [ ":" PORT ] [ PATH [ "?" QUERY ]]
其中 PATH 中的资源名称应该使用复数名词,举例:
GET https://xoyozo.net/api/Articles/{id}
POST https://xoyozo.net/api/Articles
>>> HTTP verb(对应 CURD 操作):
方法 | 功能 | ASP.NET Web API 接口返回类型(一般的) |
---|---|---|
GET | 取一个或多个资源 | T 或 IEnumerable<T> |
POST | 增加一个资源 | T |
PUT | 修改一个资源 | T |
DELETE | 删除一个资源 | void |
PATCH | 更新一个资源(资源的部分属性) | |
HEAD | 获取报头 | |
OPTIONS | 查询服务器性能或资源相关选项和需求 |
>>> 过滤信息:
如分页、搜索等
>>> 常用状态码:
200 | OK | 指示请求已成功 |
201 | Created | 资源创建成功(常见用例是一个 PUT 请求的结果) |
202 | Accepted | 该请求已被接收但尚未起作用。它是非承诺的,这意味着HTTP中没有办法稍后发送指示处理请求结果的异步响应。 |
204 | No Content | 成功 PUT(修改)或 DELETE(删除)一个资源后返回空内容(ASP.NET Web API 中将接口返回类型设置为 void 即可) |
400 | Bad Request | 服务器无法理解请求(如必填项未填、内容超长、分页大小超限等),幂等 |
401 | Unauthorized | 未授权(如用户未登录时执行了须要登录才能执行的操作),通俗地讲,是服务器告诉你,“你没有通过身份验证 - 根本没有进行身份验证或验证不正确 - 但请重新进行身份验证并再试一次。”这是暂时的,服务器要求你在获得授权后再试一次。 |
403 | Forbidden | 服务器理解请求但拒绝授权(是永久禁止的并且与应用程序逻辑相关联(如不正确的密码、尝试删除其它用户发表的文章)、IP 被禁止等),通俗地讲,是服务器告诉你,“我很抱歉。我知道你是谁 - 我相信你说你是谁 - 但你只是没有权限访问此资源。” |
404 | Not Found | 找不到请求的资源(指资源不存在,如果找到但无权访问则应返回 403) |
405 | Method Not Allowed | 请求方法被禁用(HTTP 动词) |
500 | Internal Server Error | 服务器遇到阻止它履行请求的意外情况(如数据库连接失败) |
503 | Service Unavailable | 服务器尚未准备好处理请求(常见原因是服务器因维护或重载而停机,这是临时的,可用于在单线程处理事务时遇到被锁定时的响应,如抽奖活动、抢楼活动,防止因并发导致逻辑错误) |
>> 错误处理:
C# 例:throw new HttpResponseException(HttpStatusCode.NotFound);
PHP 例:throw new Exception('文章不存在', 404);
>>> 返回结果:
JSON/XML
不要返回密码等机密字段
>>> 其它:
身份验证窗口(浏览器弹窗,类似 alert,非页面表单),明文传输,安全性不高,不建议使用。实现:
在 Headers 中添加 Authorization:Basic “用户名:密码”的 Base64 编码
Discuz! 数据库加索引
待优化的 SQL:(pre_forum_thread 表有 150 万条数据)
SELECT * FROM pre_forum_thread WHERE `fid`='62' AND `displayorder` IN('0','1','2','3','4') ORDER BY displayorder DESC, dateline DESC LIMIT 20, 20
加索引前,
EXPLAIN 结果 Extra 为:Using index condition; Using where; Using filesort
> 时间: 0.915s
加索引后:`fid`, `displayorder`, `dateline`
EXPLAIN 结果 Extra 为:Using where 或 Using index condition
> 时间: 0.001s
magapp 数据库加索引
待优化的 SQL:(mag_score_action_log 表有 200 万条数据)
SELECT COUNT(*) AS tp_count
FROM `mag_score_action_log`
WHERE action_id = 20
AND user_id = 650070
AND create_time >= 1534953600
AND create_time < 1535040000
LIMIT 1
加索引前,
EXPLAIN 结果 Extra 为:?????
> 时间: 70s
加索引后:`action_id`, `user_id`, `create_time`
EXPLAIN 结果 Extra 为:Using where; Using index
> 时间: 0.073s
待优化的 SQL:(mag_score_mission_log 表有约 55 万条数据)
SELECT COUNT(*) AS tp_count
FROM `mag_score_mission_log`
WHERE mission_id = 7
AND user_id = 650070
AND create_time >= 1534953600
AND create_time < 1535040000
LIMIT 1
加索引前,
EXPLAIN 结果 rows 为:549178
> 时间: 17.719s
加索引后:`mission_id`, `user_id`, `create_time`
EXPLAIN 结果 rows 为:1
> 时间: 0.025s
待优化的 SQL:(mag_score_mission_user 表有约 28 万条数据)
SELECT *
FROM `mag_score_mission_user`
WHERE `user_id` = 431779
AND `mission_id` = 5
AND `create_time` >= 1534953600
ORDER BY complete_count DESC
LIMIT 1
不加索引
1SIMPLEmag_score_mission_userALL282436Using where; Using filesort
> 时间: 7.325s
`user_id`, `mission_id`
1SIMPLEmag_score_mission_userrefix_us_miix_us_mi10const,const7Using where; Using filesort
时间: 0.014s
`user_id`, `mission_id`, `create_time`
1SIMPLEmag_score_mission_userrangeix_us_miix_us_mi151Using index condition; Using filesort
时间: 0.023s
`user_id`, `mission_id`, `complete_count`
1SIMPLEmag_score_mission_userrefix_us_miix_us_mi10const,const7Using where
> 时间: 0.014s
`user_id`, `mission_id`, `complete_count`, `create_time`
1SIMPLEmag_score_mission_userrefix_us_miix_us_mi10const,const7Using where
> 时间: 0.028s
`user_id`, `mission_id`, `create_time`, `complete_count`
1SIMPLEmag_score_mission_userrangeix_us_miix_us_mi151Using index condition; Using filesort
> 时间: 0.025s
其它就不一一举例了,根据 SHOW FULL PROCESSLIST 的慢查询自行加索引就行了。
打开:\WeiXinMPSDK-master\src\Senparc.Weixin.MP.Sample\Senparc.Weixin.MP.Sample.sln
工具 - NuGet 包管理器 - 管理解决方案的 NuGet 程序包 - 更新
选择所有的包(Microsoft.Net.Http 无法更新,暂不勾选),更新
Microsoft.Net.Http 是个老顽固,无法更新也无法卸载,原因是它的语言包 Microsoft.Net.Http.zh-Hans 无法安装。我们切换到“已安装”选项卡,搜索“Microsoft.Net.Http”,选中 Microsoft.Net.Http.zh-Hans 并卸载它,现在我们可以更新 Microsoft.Net.Http 了。
【可能】运行报错:
“/”应用程序中的服务器错误。
配置错误
说明: 在处理向该请求提供服务所需的配置文件时出错。请检查下面的特定错误详细信息并适当地修改配置文件。
分析器错误消息: 创建 system.web.webPages.razor/host 的配置节处理程序时出错: 未能加载文件或程序集“System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
源错误:行 4: <configSections>
行 5: <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
行 6: <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
行 7: <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
行 8: </sectionGroup>
源文件: E:\WeiXinMPSDK-master\src\Senparc.Weixin.MP.Sample\Senparc.Weixin.MP.Sample\views\web.config 行: 6展开 Senparc.Weixin.MP.Sample 引用,查看 System.Web.Razor 的属性,复制版本号。打开 \views\web.config,修改 System.Web.WebPages.Razor 的 Version(有 3 处)。
对于小型开发项目来说,我习惯将所有代码放在同一个项目(Project)中来,所以做了以下处理:(盛派官方分离这些代码是为了同时供 MVC 和 WebForms 重用)
在 Senparc.Weixin.MP.Sample 中添加文件夹 CommonService,将 Senparc.Weixin.MP.Sample.CommonService 项目中的文件夹和文件(.config 除外)拖到 CommonService 文件夹中。
卸载 Senparc.Weixin.MP.Sample.CommonService 项目并删除引用。
在解决方案的 Libraries 文件夹中,我们看到 Sample 项目了以下功能模块,这些就是 Senparc.Weixin 的源代码,如果不需要修改,可以卸载它们改为使用从 NuGet 获取,以便随时更新到最新版本:
Senparc.WebSocket
Senparc.Weixin
Senparc.Weixin.MP
Senparc.Weixin.MP.MvcExtension NuGet 中对应的包名为:Senparc.Weixin.MP.MVC
Senparc.Weixin.Open
Senparc.Weixin.Work
Senparc.Weixin.WxOpen
Senparc.Weixin.Cache.Memcached
Senparc.Weixin.Cache.Redis
卸载这些项目,并在 NuGet 中安装这些模块(搜索“Senparc.Weixin”第一页都在了,认准作者 Jeffrey Su)
单元测试项目中的引用也按需更换,当然也可以卸载这些单元测试项目(视情况保留 Senparc.Weixin.MP.Sample.Tests) 。
【可能】运行报错
HTTP Error 500.19 - Internal Server Error
无法访问请求的页面,因为该页的相关配置数据无效。
配置源:
134: </sessionState>
135: <sessionState customProvider="Memcached" mode="Custom">
136: <providers>
可以在 Global.asax 的 RegisterWeixinCache() 中修改 Memcached 配置。
或者打开 Web.config,找到 Memcached 所在的 sessionState 标签,注释掉,这样程序自动使用上方的 InProc(应用进程内)。
如果开启了 ASP.NET State Service 服务,那么建议改用 StateServer,与 Custom 一样需要序列化,方便日后改用 Memcached 或 Redis。
再次更新 NuGet,否则会提示无法加载 Enyim.Caching 的错误(报错行:MemcachedObjectCacheStrategy.RegisterServerList(memcachedConfig);)。
接下来,进入微信公众平台,在左侧 开发 - 基本配置 中设置相关参数(填写“服务器地址(URL)”如“https://weixin.xoyozo.net/weixin/”),打开 Sample 项目中的 Web.config,配置我们的公众号参数。
将项目发布到服务器上,尝试向公众号发送消息吧。
单元测试
设置单元测试中的公众号配置项:打开 Senparc.Weixin.MP.Test/CommonAPIs/CommonApiTest.cs,在 AppConfig 方法中可以看到支持两种配置方式,在 Senparc.Weixin.MP.Test/Config/test.config 配置文件中配置,或直接在 CommonApiTest.cs 文件中配置,前者格式如下,后者建议只在个人测试项目中使用。
<Config> <AppId>YourAppId</AppId> <Secret>YourSecret</Secret> <MchId>YourMchId</MchId> <TenPayKey>YourTenPayKey</TenPayKey> <TenPayCertPath>YourTenPayCertPath</TenPayCertPath> <!-- 小程序 --> <WxOpenAppId>YourOpenAppId</WxOpenAppId> <WxOpenSecret>YourWxOpenSecret</WxOpenSecret> </Config>
另外,将 _testOpenId 值改为自己的微信号在本公众号上的 openid。
微信网页授权(OAuth2)
打开 OAuth2Controller 控制器,将“Index”Action 中的盛派的网址(有 2 处)改成:
Request.Url.Scheme + "://" + Request.Url.Authority + "/Oauth2/……
未完待续……