报错:
HTTP Error 500.30 - ASP.NET Core app failed to start
Common solutions to this issue:
The app failed to start
The app started but then stopped
The app started but threw an exception during startup
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=2028265
解决:
直接运行网站根目录的 .exe 启动文件可以找到答案。
一个常见的原因是:因 nuget 包升级(特别是需要服务器端安装组件的包)导致的发布后仍然是低版本的包,删除项目中的 /obj/ 目录重新发布即可。
使用 JS 根据屏幕宽度来计算页面尺寸和字体大小并不是一个好办法。
rem 单位是跟随网页根元素的 font-size 改变而自动改变的,是一个相对的长度单位,非常适合在不同手机界面上自适应屏幕大小。
一般的手机浏览器的默认字体大小为 16px。即:
:root { font-size: 16px; } /* 在 HTML 网页中,:root 选择器相当于 html */也就是说,如果我定义一个宽度为 1rem,那么它的实际宽度为 16px。反过来说,如果设计稿宽度为 1000px,那么相当于 1000÷16=62.5rem。因此,我们设置一个 62.5rem 的宽度,即可正常显示 1000px 的设计效果。
为了适应不同屏幕尺寸的手机,只需按比例换算更改 :root 的 font-size 即可。这个比例是由“窗口宽度 ÷ 设计稿宽度”得到的,姑且称它为“窗设比”。
以 iPhone X 逻辑宽度 375px 为例,设计稿宽度 1000px 时,窗设比为:0.375。:root 的 font-size 将会被重置为 16 * 0.375 = 6px。上面的 62.5rem 宽度将对应 iPhone X 宽度为 62.5 * 6 = 375px,正好是屏幕逻辑宽度。
根据这个思路,理论上,我们只需要使用 CSS 将 :root 的 font-size 设置为 1px,然后使用 JS 重置为与“窗设比”相乘的积(本例中将被重置为 0.375px)。这样,我们可以不通过换算,只需要更改单位,将设计稿中的 500px 直接写入到 CSS 为 500rem,即可实现在 iPhone X 上显示逻辑宽度为(500 * 0.375 =)187.5px,即设计稿中的 1/2 宽度对应到屏幕上 1/2 的宽度。
实际上,部分安卓手机(如华为某旗舰机)不支持 :root 的 font-size 小于 12px,其它一些浏览器也会出现小于 12px 的文字以 12px 显示。
为了避免在任何环节出现小于 12px 的 font-size 值,且不增加设计稿尺寸到 CSS 数值的换算难度,我们设计了以下思路:
约定“设样比(设计稿的 px 值与 CSS 的 rem 值的比)”为 100;
使用 JS 将 :root 的 font-size 重置为“设样比”与“窗设比(窗口宽度 ÷ 设计稿宽度)”的乘积;
计算 CSS 时的 rem 值只需从设计稿中获取 px 值再除以“设样比”100 即可。
这样做的另一个好处是,不用要求设计师必须按多少尺寸来设计,当然按主流尺寸来建议是可行的。
完整代码(jQuery 版):
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>Index</title>
<style>
body { margin: 0; text-align: center; }
#app { margin: 0 auto; background-color: #EEE; display: none; }
/* 长度计算方法:从设计稿获得长度(例如 160px),除以 px2rem 值(本例为 100),得到 1.6rem */
.whole { background-color: #D84C40; width: 10rem; }
.half { background-color: #3296FA; width: 5rem; }
.half2 { background-color: #3296FA; width: 5rem; margin-left: 5rem; }
</style>
</head>
<body>
<div id="app">
<div class="whole">100%</div>
<div class="half">50%</div>
<div class="half2">50%</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// [函数] 重置尺寸
function fn_resize() {
// 设计稿宽度(px)
var designsWidth = 1000;
// 约定的“设计稿 px 值与 CSS rem 值的比”,为方便计算,一般无需改动
var px2rem = 100;
// 限制 #app 的最大宽度为设计稿宽度
$('#app').css('max-width', designsWidth).css('min-height', $(window).height());
// 重置 :root 的 font-size
var appWidth = Math.min($(window).width(), designsWidth);
$(':root').css('font-size', px2rem * appWidth / designsWidth);
$('#app').show();
}
// 页面加载完成后重置尺寸
$(fn_resize);
// 改变窗口大小时重置尺寸
$(window).resize(fn_resize);
</script>
</body>
</html>完整代码(Vue2 版):
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>Index</title>
<style>
body { margin: 0; text-align: center; }
#app { margin: 0 auto; background-color: #EEE; }
/* 长度计算方法:从设计稿获得长度(例如 160px),除以 px2rem 值(本例为 100),得到 1.6rem */
.whole { background-color: #D84C40; width: 10rem; }
.half { background-color: #3296FA; width: 5rem; }
.half2 { background-color: #3296FA; width: 5rem; margin-left: 5rem; }
</style>
</head>
<body>
<div id="app" v-bind:style="{ maxWidth: designsWidth + 'px', minHeight: appMinHeight + 'px' }" style="display: none;" v-show="appShow">
<div class="whole">100%</div>
<div class="half">50%</div>
<div class="half2">50%</div>
<div>appWidth: {{ appWidth }}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
var app = new Vue({
el: '#app',
data: {
// 设计稿宽度(px)
designsWidth: 1000,
// 约定的“设计稿 px 值与 CSS rem 值的比”,为方便计算,一般无需改动
px2rem: 100,
// #app 的 width
appWidth: 0, // 勿改
appMinHeight: 0, // 勿改
appShow: false, // 勿改
},
mounted: function () {
// 页面加载完成后重置尺寸
this.fn_resize();
const that = this;
// 改变窗口大小时重置尺寸
window.onresize = () => {
return (() => {
console.log('RUN window.onresize()');
that.fn_resize();
})();
};
},
watch: {
// 侦听 appWidth 更改 root 的 font-size
appWidth: function () {
console.log('RUN watch: appWidth');
var root = document.getElementsByTagName("html")[0];
root.style.fontSize = (this.px2rem * this.appWidth / this.designsWidth) + 'px';
this.appShow = true;
}
},
methods: {
fn_resize: function () {
console.log('RUN methods: fn_resize()');
this.appWidth = Math.min(document.body.clientWidth, this.designsWidth);
this.appMinHeight = document.documentElement.clientHeight;
}
}
});
</script>
</body>
</html>完整代码(Vue3 版):
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>Index</title>
<style>
body { margin: 0; text-align: center; }
#app > div { display: none; margin: 0 auto; background-color: #EEE; }
/* 长度计算方法:从设计稿获得长度(例如 160px),除以 px2rem 值(本例为 100),得到 1.6rem */
.whole { background-color: #D84C40; width: 10rem; }
.half { background-color: #3296FA; width: 5rem; }
.half2 { background-color: #3296FA; width: 5rem; margin-left: 5rem; }
</style>
</head>
<body>
<div id="app">
<div style="display: none;" v-bind:style="{ maxWidth: designsWidth + 'px', minHeight: appMinHeight + 'px', display: appShow ? 'block' : 'none' }">
<div class="whole">100%</div>
<div class="half">50%</div>
<div class="half2">50%</div>
<div>appWidth: {{ appWidth }}</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
<script>
const app = Vue.createApp({
data: function () {
return {
// 设计稿宽度(px)
designsWidth: 1000,
// 约定的“设计稿 px 值与 CSS rem 值的比”,为方便计算,一般无需改动
px2rem: 100,
// #app 的 width
appWidth: 0, // 勿改
appMinHeight: 0, // 勿改
appShow: false, // 勿改
}
},
mounted: function () {
// 页面加载完成后重置尺寸
this.fn_resize();
const that = this;
// 改变窗口大小时重置尺寸
window.onresize = () => {
return (() => {
console.log('RUN window.onresize()');
that.fn_resize();
})();
};
},
watch: {
// 侦听 appWidth 更改 root 的 font-size
appWidth: function () {
console.log('RUN watch: appWidth');
var root = document.getElementsByTagName("html")[0];
root.style.fontSize = (this.px2rem * this.appWidth / this.designsWidth) + 'px';
this.appShow = true;
}
},
methods: {
fn_resize: function () {
console.log('RUN methods: fn_resize()');
this.appWidth = Math.min(document.body.clientWidth, this.designsWidth);
this.appMinHeight = document.documentElement.clientHeight;
}
}
});
const vm = app.mount('#app');
</script>
</body>
</html>示例中 CSS 初始 :root 的 font-size 为 16px(一个较小值,防止页面加载时瞬间出现大号文字影响用户体验),经过 fn_resize 后,:root 的 font-size 被设置为(100 * 375 / 1000 =)37.5px(iPhone X 中),那么宽度为 1000px 的设计稿中的 500px 换算到 CSS 中为 5rem,也即 37.5 * 5 = 187.5px,就是 iPhone X 的屏幕宽度的一半。
示例中 id 为 app 的 div 是用来在 PC 浏览器中限制页面内容最大宽度的(类似微信公众号发布的文章),如果网页不需要在 PC 端显示,jQuery 版代码中的 $('#app').width() 可以用 $(window).width() 来代替。
这个 div#app 一般设计有背景色,用于在宽度超过设计稿的设备上显示时区别于 body 的背景。但是当网页内容不超过一屏时,div#app 高度小于窗口,示例中与 appMinHeight 相关的代码就是为了解决这个问题。
示例中 div#app 隐藏/显示相关代码用于解决在页面加载初期由于 font-size 值变化引起的一闪而过的排版错乱。

最后补充一点,如果改变窗口大小时涉及执行耗时的操作,为避免页面卡顿,可以参考这篇文章添加函数防抖:https://xoyozo.net/Blog/Details/js-function-anti-shake
| 返回状态 | ASP.NET MVC | ASP.NET Core | ASP.NET Web API |
| 200 视图 | return View(); | return View(); | - |
| 200 带模型的视图 | return View(Model); | return View(Model); | - |
| 200 空内容 | return new EmptyResult(); | return Ok(); | return Ok(); |
| 200 文本 | return Content(string); | return Ok(string); return Content(string); | return Ok(string); return Content(string); |
| 200 JSON | return Json(object); | return Json(T); // 强制 JSON return Ok(T); // 请求时可指定 Content-Type | return Json(T); // 强制 JSON return Ok(T); // 请求时可指定 Content-Type |
| 200 JaveScript | return JavaScript(string script); | ||
| 200 文件 | return File(); | return File(); return PhysicalFile(); | return File(); return PhysicalFile(); |
| 201 已创建 | return Created(location, content); 用于 Post 接口 | ||
| 301 永久跳转 | return RedirectPermanent(url); return RedirectToActionPermanent(url); return RedirectToRoutePermanent(object); | return RedirectPermanent(url); return RedirectToActionPermanent(url); return RedirectToRoutePermanent(object); | |
| 302 临时跳转 | return Redirect(url); return RedirectToAction(url); return RedirectToRoute(object); | return Redirect(url); return RedirectToAction(url); return RedirectToRoute(object); | return Redirect(url); return RedirectToRoute(object); |
| 400 错误的请求 | return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest); | return BadRequest(msg); | return BadRequest(msg); |
| 401 未授权 | return new HttpUnauthorizedResult("描述"); | return Unauthorized(msg); | return Unauthorized(msg); |
| 404 找不到文件或目录 | return HttpNotFound(); | return NotFound(msg); | return NotFound(msg); |
| 直接指定状态码 | return new HttpStatusCodeResult(HttpStatusCode.*); public enum HttpStatusCode { // // 摘要: // 等效于 HTTP 状态 100。 System.Net.HttpStatusCode.Continue 指示客户端可能继续其请求。 Continue = 100, // // 摘要: // 等效于 HTTP 状态 101。 System.Net.HttpStatusCode.SwitchingProtocols 指示正在更改协议版本或协议。 SwitchingProtocols = 101, // // 摘要: // 等效于 HTTP 状态 200。 System.Net.HttpStatusCode.OK 指示请求成功,且请求的信息包含在响应中。 这是最常接收的状态代码。 OK = 200, // // 摘要: // 等效于 HTTP 状态 201。 System.Net.HttpStatusCode.Created 指示请求导致在响应被发送前创建新资源。 Created = 201, // // 摘要: // 等效于 HTTP 状态 202。 System.Net.HttpStatusCode.Accepted 指示已接受请求做进一步处理。 Accepted = 202, // // 摘要: // 等效于 HTTP 状态 203。 System.Net.HttpStatusCode.NonAuthoritativeInformation 指示返回的元信息来自缓存副本而不是原始服务器,因此可能不正确。 NonAuthoritativeInformation = 203, // // 摘要: // 等效于 HTTP 状态 204。 System.Net.HttpStatusCode.NoContent 指示已成功处理请求并且响应已被设定为无内容。 NoContent = 204, // // 摘要: // 等效于 HTTP 状态 205。 System.Net.HttpStatusCode.ResetContent 指示客户端应重置(而非重新加载)当前资源。 ResetContent = 205, // // 摘要: // 等效于 HTTP 状态 206。 System.Net.HttpStatusCode.PartialContent 指示响应是包括字节范围的 GET 请求所请求的部分响应。 PartialContent = 206, // // 摘要: // 等效于 HTTP 状态 300。 System.Net.HttpStatusCode.MultipleChoices 指示请求的信息有多种表示形式。 默认操作是将此状态视为重定向,并遵循与此响应关联的 // Location 标头的内容。 MultipleChoices = 300, // // 摘要: // 等效于 HTTP 状态 300。 System.Net.HttpStatusCode.Ambiguous 指示请求的信息有多种表示形式。 默认操作是将此状态视为重定向,并遵循与此响应关联的 // Location 标头的内容。 Ambiguous = 300, // // 摘要: // 等效于 HTTP 状态 301。 System.Net.HttpStatusCode.MovedPermanently 指示请求的信息已移到 Location // 头中指定的 URI 处。 接收到此状态时的默认操作为遵循与响应关联的 Location 标头。 MovedPermanently = 301, // // 摘要: // 等效于 HTTP 状态 301。 System.Net.HttpStatusCode.Moved 指示请求的信息已移到 Location 头中指定的 URI // 处。 接收到此状态时的默认操作为遵循与响应关联的 Location 标头。 原始请求方法为 POST 时,重定向的请求将使用 GET 方法。 Moved = 301, // // 摘要: // 等效于 HTTP 状态 302。 System.Net.HttpStatusCode.Found 指示请求的信息位于 Location 标头中指定的 URI // 处。 接收到此状态时的默认操作为遵循与响应关联的 Location 标头。 原始请求方法为 POST 时,重定向的请求将使用 GET 方法。 Found = 302, // // 摘要: // 等效于 HTTP 状态 302。 System.Net.HttpStatusCode.Redirect 指示请求的信息位于 Location 标头中指定的 // URI 处。 接收到此状态时的默认操作为遵循与响应关联的 Location 标头。 原始请求方法为 POST 时,重定向的请求将使用 GET 方法。 Redirect = 302, // // 摘要: // 等效于 HTTP 状态 303。 作为 POST 的结果,System.Net.HttpStatusCode.SeeOther 将客户端自动重定向到 Location // 标头中指定的 URI。 用 GET 生成对 Location 标头所指定的资源的请求。 SeeOther = 303, // // 摘要: // 等效于 HTTP 状态 303。 作为 POST 的结果,System.Net.HttpStatusCode.RedirectMethod 将客户端自动重定向到 // Location 标头中指定的 URI。 用 GET 生成对 Location 标头所指定的资源的请求。 RedirectMethod = 303, // // 摘要: // 等效于 HTTP 状态 304。 System.Net.HttpStatusCode.NotModified 指示客户端的缓存副本是最新的。 未传输此资源的内容。 NotModified = 304, // // 摘要: // 等效于 HTTP 状态 305。 System.Net.HttpStatusCode.UseProxy 指示请求应使用位于 Location 标头中指定的 // URI 的代理服务器。 UseProxy = 305, // // 摘要: // 等效于 HTTP 状态 306。 System.Net.HttpStatusCode.Unused 是未完全指定的 HTTP/1.1 规范的建议扩展。 Unused = 306, // // 摘要: // 等效于 HTTP 状态 307。 System.Net.HttpStatusCode.TemporaryRedirect 指示请求信息位于 Location // 标头中指定的 URI 处。 接收到此状态时的默认操作为遵循与响应关联的 Location 标头。 原始请求方法为 POST 时,重定向的请求还将使用 POST // 方法。 TemporaryRedirect = 307, // // 摘要: // 等效于 HTTP 状态 307。 System.Net.HttpStatusCode.RedirectKeepVerb 指示请求信息位于 Location // 标头中指定的 URI 处。 接收到此状态时的默认操作为遵循与响应关联的 Location 标头。 原始请求方法为 POST 时,重定向的请求还将使用 POST // 方法。 RedirectKeepVerb = 307, // // 摘要: // 等效于 HTTP 状态 400。 System.Net.HttpStatusCode.BadRequest 指示服务器未能识别请求。 如果没有其他适用的错误,或者不知道准确的错误或错误没有自己的错误代码,则发送 // System.Net.HttpStatusCode.BadRequest。 BadRequest = 400, // // 摘要: // 等效于 HTTP 状态 401。 System.Net.HttpStatusCode.Unauthorized 指示请求的资源要求身份验证。 WWW-Authenticate // 标头包含如何执行身份验证的详细信息。 Unauthorized = 401, // // 摘要: // 等效于 HTTP 状态 402。 保留 System.Net.HttpStatusCode.PaymentRequired 以供将来使用。 PaymentRequired = 402, // // 摘要: // 等效于 HTTP 状态 403。 System.Net.HttpStatusCode.Forbidden 指示服务器拒绝满足请求。 Forbidden = 403, // // 摘要: // 等效于 HTTP 状态 404。 System.Net.HttpStatusCode.NotFound 指示请求的资源不在服务器上。 NotFound = 404, // // 摘要: // 等效于 HTTP 状态 405。 System.Net.HttpStatusCode.MethodNotAllowed 指示请求的资源上不允许请求方法(POST // 或 GET)。 MethodNotAllowed = 405, // // 摘要: // 等效于 HTTP 状态 406。 System.Net.HttpStatusCode.NotAcceptable 指示客户端已用 Accept 标头指示将不接受资源的任何可用表示形式。 NotAcceptable = 406, // // 摘要: // 等效于 HTTP 状态 407。 System.Net.HttpStatusCode.ProxyAuthenticationRequired 指示请求的代理要求身份验证。 // Proxy-authenticate 标头包含如何执行身份验证的详细信息。 ProxyAuthenticationRequired = 407, // // 摘要: // 等效于 HTTP 状态 408。 System.Net.HttpStatusCode.RequestTimeout 指示客户端没有在服务器期望请求的时间内发送请求。 RequestTimeout = 408, // // 摘要: // 等效于 HTTP 状态 409。 System.Net.HttpStatusCode.Conflict 指示由于服务器上的冲突而未能执行请求。 Conflict = 409, // // 摘要: // 等效于 HTTP 状态 410。 System.Net.HttpStatusCode.Gone 指示请求的资源不再可用。 Gone = 410, // // 摘要: // 等效于 HTTP 状态 411。 System.Net.HttpStatusCode.LengthRequired 指示缺少必需的 Content-length // 标头。 LengthRequired = 411, // // 摘要: // 等效于 HTTP 状态 412。 System.Net.HttpStatusCode.PreconditionFailed 指示为此请求设置的条件失败,且无法执行此请求。条件是用条件请求标头(如 // If-Match、If-None-Match 或 If-Unmodified-Since)设置的。 PreconditionFailed = 412, // // 摘要: // 等效于 HTTP 状态 413。 System.Net.HttpStatusCode.RequestEntityTooLarge 指示请求太大,服务器无法处理。 RequestEntityTooLarge = 413, // // 摘要: // 等效于 HTTP 状态 414。 System.Net.HttpStatusCode.RequestUriTooLong 指示 URI 太长。 RequestUriTooLong = 414, // // 摘要: // 等效于 HTTP 状态 415。 System.Net.HttpStatusCode.UnsupportedMediaType 指示请求是不受支持的类型。 UnsupportedMediaType = 415, // // 摘要: // 等效于 HTTP 状态 416。 System.Net.HttpStatusCode.RequestedRangeNotSatisfiable 指示无法返回从资源请求的数据范围,因为范围的开头在资源的开头之前,或因为范围的结尾在资源的结尾之后。 RequestedRangeNotSatisfiable = 416, // // 摘要: // 等效于 HTTP 状态 417。 System.Net.HttpStatusCode.ExpectationFailed 指示服务器未能符合 Expect // 标头中给定的预期值。 ExpectationFailed = 417, // // 摘要: // 等效于 HTTP 状态 426。 System.Net.HttpStatusCode.UpgradeRequired 指示客户端应切换为诸如 TLS/1.0 // 之类的其他协议。 UpgradeRequired = 426, // // 摘要: // 等效于 HTTP 状态 500。 System.Net.HttpStatusCode.InternalServerError 指示服务器上发生了一般错误。 InternalServerError = 500, // // 摘要: // 等效于 HTTP 状态 501。 System.Net.HttpStatusCode.NotImplemented 指示服务器不支持请求的函数。 NotImplemented = 501, // // 摘要: // 等效于 HTTP 状态 502。 System.Net.HttpStatusCode.BadGateway 指示中间代理服务器从另一代理或原始服务器接收到错误响应。 BadGateway = 502, // // 摘要: // 等效于 HTTP 状态 503。 System.Net.HttpStatusCode.ServiceUnavailable 指示服务器暂时不可用,通常是由于过多加载或维护。 ServiceUnavailable = 503, // // 摘要: // 等效于 HTTP 状态 504。 System.Net.HttpStatusCode.GatewayTimeout 指示中间代理服务器在等待来自另一个代理或原始服务器的响应时已超时。 GatewayTimeout = 504, // // 摘要: // 等效于 HTTP 状态 505。 System.Net.HttpStatusCode.HttpVersionNotSupported 指示服务器不支持请求的 // HTTP 版本。 HttpVersionNotSupported = 505 } |
附 ASP.NET Form 相关:
400:
Response.StatusCode = 400;
Response.Write("错误提示");
Response.End();异常提示:
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 / 10Gbps(55米内) | 250MHz | 非屏蔽/屏蔽 | 内部通常有十字骨架,全双工,改善串扰及回波损耗 |
| 超六类(CAT6A) | 10Gbps | 500MHz | 屏蔽为主 | 通常带屏蔽层,改善串扰、衰减、信噪比等 |
| 七类线(CAT7) | 10Gbps | 600MHz | 屏蔽 | 每对线对单独屏蔽+总屏蔽,适应万兆位以太网技术 |
| 八类线(CAT8) | 25Gbps / 40Gbps(30米内) | 2000MHz | 屏蔽 | 专为短距离高速连接设计 |
普通家庭装修布线建议上到千兆网络(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 修饰即可。
