‫۶ سال و ۶ ماه قبل، پنجشنبه ۲ فروردین ۱۳۹۷، ساعت ۱۹:۳۱
یک نکته‌ی تکمیلی: جایگزینی bower با npm

bower یک فناوری منسوخ شده‌است و اگر بخواهیم bower.json ذکر شده‌ی در این مطلب را با package.json مربوط به npm جایگزین کنیم، به یک چنین محتوایی خواهیم رسید:
{
  "name": "testwebapp",
  "version": "1.0.0",
  "description": "",
  "scripts": {},
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bootstrap": "^3.3.7",
    "jquery": "^2.2.4",
    "jquery-ajax-unobtrusive": "^3.2.4",
    "jquery-validation": "^1.17.0",
    "jquery-validation-unobtrusive": "^3.2.8"
  }
}
پس از ایجاد فایل package.json فوق، کافی است دستور npm install را در ریشه‌ی پروژه وارد کنید تا این بسته‌ها دریافت و نصب شوند.
سپس بر اساس مسیرهای پوشه‌ی node_modules جدید، فایل bundleconfig.json چنین محتوایی را پیدا می‌کند:
[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "node_modules/bootstrap/dist/css/bootstrap.min.css",
      "wwwroot/css/site.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "node_modules/jquery/dist/jquery.min.js",
      "node_modules/jquery-validation/dist/jquery.validate.min.js",
      "node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js",
      "node_modules/jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.min.js",
      "node_modules/bootstrap/dist/js/bootstrap.min.js",
      "wwwroot/js/site.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    },
    "sourceMap": false
  }
]
و در آخر فایل Layout.cshtml_ برنامه به این صورت ساده خواهد شد (فقط خروجی‌های نهایی css و js حاصل از BundlerMinifier در اینجا قید می‌شوند؛ که حاصل یکی کردن و فشرده سازی تمام آن‌ها است):
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - DNTCommon.Web.Core.TestWebApp</title>
    <link href="~/css/site.min.css" rel="stylesheet" asp-append-version="true" />
</head>

<body>
    <div>
        @RenderBody()
    </div>

    <script src="~/js/site.min.js" type="text/javascript" asp-append-version="true"></script> 
    @RenderSection("Scripts", required: false)
</body>
</html>
البته با این شرط که تنظیمات ذیل در فایل csproj برنامه موجود باشند:
<Project Sdk="Microsoft.NET.Sdk.Web">
  <Target Name="PrecompileScript" BeforeTargets="BeforeBuild">
    <Exec Command="dotnet bundle" />
  </Target>
  <ItemGroup>
    <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.6.362" />
  </ItemGroup>
</Project>
‫۶ سال و ۶ ماه قبل، دوشنبه ۲۸ اسفند ۱۳۹۶، ساعت ۰۴:۵۳
مطلقا نباید از Local System استفاده کنید. در این حالت کاربر وارد شده‌ی به سایت توسط برنامه‌ی وب جاری، دسترسی مدیریتی بر روی سیستم عامل جاری را پیدا می‌کند و اگر باگی در برنامه پیدا شود، قادر به اعمال هر نوع تغییری بر روی کل سیستم عامل خواهد بود.
‫۶ سال و ۶ ماه قبل، یکشنبه ۲۷ اسفند ۱۳۹۶، ساعت ۲۲:۲۴
در مورد خالی بودن فایل لاگ گزینه stdoutLogFile
<aspNetCore stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
- اگر این مورد به مسیر logs\stdout\. تنظیم شده‌است، باید پوشه‌ی logs را در ریشه‌ی پروژه به صورت دستی ایجاد کنید؛ و گرنه IIS آن‌را به صورت خودکار ایجاد نخواهد کرد.
- کاربر App Pool برنامه (با نام پیش‌فرض «
IIS AppPool\DefaultAppPool») باید دسترسی نوشتن در این پوشه را داشته باشد؛ وگرنه فایل لاگی در آن ایجاد نخواهد شد.
- همچنین اگر با رعایت تمام این موارد، محتوای این فایل تولید شده باز هم خالی بود، یکبار IIS را ری‌استارت کنید. ممکن است IIS کار نوشتن در فایل لاگ را تمام نکرده باشد و با این کار مجبور به تکمیل و بستن فایل می‌شود.
‫۶ سال و ۶ ماه قبل، یکشنبه ۲۷ اسفند ۱۳۹۶، ساعت ۱۸:۰۷
اگر جزئیات هیچ خطایی را مشاهده نمی‌کنید، به صورت زیر عمل کنید:
- در فایل web.config، محیط کاری را به صورت موقت به حالت توسعه تنظیم کنید:
<aspNetCore ...... > 
  <environmentVariables>
    <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" /> 
  </environmentVariables> 
</aspNetCore>
- سپس در ابتدای متد Configure فایل آغازین برنامه، تنظیم نمایش خطاهای توسعه دهندگان را قرار دهید:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
{    
    if (env.IsDevelopment()) 
    {     
        app.UseDeveloperExceptionPage(); 
    }
‫۶ سال و ۶ ماه قبل، شنبه ۲۶ اسفند ۱۳۹۶، ساعت ۱۵:۴۸
طول عمر میان افزارها به صورت singleton تعریف می‌شود. به همین جهت فقط وابستگی‌هایی با طول عمر singleton را هم می‌توانید در سازنده‌ی آن‌ها تزریق کنید؛ مانند IHttpContextAccessor در مثال شما. سایر مواردی که این طول عمر را ندارند، باید به این صورت تزریق شوند:
public async Task Invoke(HttpContext context, IIP iip)
{

}
در این حالت هست که طول عمرهایی مانند scoped یا transient معنا پیدا می‌کنند. اگر سرویس‌هایی با این طول عمرها در سازنده‌ی یک کلاس singleton تزریق شوند، دیگر هیچگاه وهله سازی مجدد نخواهند شد و دقیقا به صورت singleton رفتار می‌کنند؛ چون سازنده‌ی کلاس singleton فقط یکبار در طول عمر برنامه فراخوانی می‌شود.
‫۶ سال و ۶ ماه قبل، سه‌شنبه ۲۲ اسفند ۱۳۹۶، ساعت ۱۵:۱۴
یک نکته‌ی تکمیلی: پردازش صحیح X-Content-Type-Options در کروم 65

اگر هدر X-Content-Type-Options را به nosniff تنظیم کرده باشید، کروم 65 از اجرای فایل‌های اسکریپت با خطای زیر سر باز می‌زند:
Refused to execute script from '<URL>' because its MIME type ('') is not executable, and strict MIME type checking is enabled.
چون تنظیم پیش فرض app.UseStaticFiles، هیچ نوع content-type ایی را نمی‌شناسد.
برای رفع آن باید به صورت زیر content-type صحیحی را به فایل‌های اسکریپت تولیدی نسبت داد:
var provider = new FileExtensionContentTypeProvider();
app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = provider
});