Publish کردن و اجرای برنامه ASP.NET Core با IIS

چهارشنبه 24 شهریور 1395

زمانی که شما یک برنامه ASP.NET Core می سازید و می خواهید آن را بر روی IIS اجرا کنید، خواهید فهمید که روش اجرای برنامه های ASP.NET Core به صورت اساسی با نسخه های قبلی ASP.NET متفاوت است. در این مقاله، ما نحوه اجرای برنامه های ASP.NET Core و سپس قرار دادن آن بر روی IIS را شرح خواهیم داد.

Publish کردن و اجرای برنامه ASP.NET Core با IIS

IIS  و  ASP.NET Core

مهم ترین ویژگی در زمینه ی میزبانی کردن برنامه های ASP.NET Core این است که به صورت مستقل فعالیت می کنند و نیازی به پردازش Console application ندارند. این نوع برنامه ها در IIS میزبانی نمی شوند و نیازی به آن ندارند. برنامه های ASP.NET Core وب سرور های خاص خودشان را دارند و درخواست های داخلی را با استفاده از این سرور ها پردازش می کنند.

با همه ی این مواردی که گفتیم ، شما می توانید IIS را به عنوان یک front end proxy برای برنامه های ASP.NET Core اجرا کنید، زیرا Kestrel یک وب سرور خام است که برخی از امکانات وب سرور هایی مانند IIS را ندارد. این مورد، در حقیقت یک تمرین پیشنهادی بر روی Windows برای فراهم کردن port 80/443 است که kestrel به صورت مستقیم، از آن پشتیبانی نمی کند. Windows IIS (و یا سایر reverse proxy ها ) همچنان به عنوان بخش مهمی از سرور محسوب می شوند، حتی در برنامه های ASP.NET Core .

بیایید نگاهی بندازیم و ببینیم چطور IIS با برنامه های ASP.NET Core سازگاری پیدا می کند.

عملیات Hosting به شیوه کلاسیک برای برنامه های ASP.NET

قبل از این که به روش میزبانی ASP.NET Core بپردازیم، بیایید ابتدا مروری بر شیوه اجرای برنامه های ASP.NET کلاسیک بپردازیم.

 

در یک برنامه ی ASP.NET کلاسیک، همه موارد در داخل یک IIS Worker Process میزبانی می شوند(w3wp.exe) که IIS Application Pool ما محسوب می شود. AppPool برنامه ی ASP.NET شما را میزبانی می کند و برنامه ی شما به عنوان یک نمونه در IIS قرار می گیرد. runtime manager یک نمونه از .NET Runtime بر روی برنامه شما می سازد و شی HttpRuntime را ایجاد می کند که در مراحل بعدی برای ایجاد درخواست ها از طریق خط لوله ی ASP.NET مورد استفاده قرار می گیرد. درخواست ها از طریق http.sys driver می آیند و به سمت سایتی که در Application Pool نگاشت شده است، راهنمایی می شوند و نمونه HttpRuntime نیز در آنجا میزبانی می شود.

ASP.NET Core  همراه با   IIS

داستان در مورد ASP.NET Core کمی متفاوت است زیرا بر روی IIS worker process اجرا نمی شود و بر روی یک Console application جداگانه که یک وب سرور را راه اندازی می کند، اجرا می شود. این وب سرور با استفاده از کامپوننت Kestrel این کار را انجام می دهد. Kestrel یک .NET Web Server است که به صورت بسیار بنیادی برای بهینه سازی راندمان کار، پیاده سازی شده است. این راه، راه سریع و کاربردی برای وارد کردن  درخواست های شبکه به برنامه شما است. اما در این حالت هیچ گونه سرویسی برای Web management به عنوان یک سرور قدرتمند مانند IIS در اختیار نداریم.

اگرشما عملیات اجرا را بر روی Windows انجام دهید، ممکن است برای این که امکانات زیربنایی مانند port 80/443 را در اختیار داشته باشید، Kestrel را نیز به کار بگیرید . در این صورت، Host Header ها، مدیریت زمان اجرای پردازش ها و مدیریت گواهی ها نیز در دسترس شما خواهند بود.

در تصویر زیر می توانید ببینید که زمانی که یک برنامه ی ASP.NET Core را درکنار IIS Web front اجرا می کنید، چه اتفاقی می افتد.

برنامه های ASP.NET Core ، برنامه های Console مستقلی هستند که از طریق dotnet runtime command به کار گرفته می شوند. آن ها در یک IIS worker process بارگذاری نمی شوند، بلکه در یک IIS module به نام AspNetCoreModule اجرا می شوند.

 

AspNetCoreModule باید بر روی سرور شما نصب شود و یک بخش از ASP.NET Core Server Hosting Bundle محسوب می شود.

 

زمانی که شما hosting bundle را نصب می کنید، AspNetCoreModule در لیست IIS native module list در دسترس شما قرار خواهد گرفت:

AspNetCoreModule یک native IIS module است که خیلی سریع در چرخه درخواست ، وارد IIS pipeline می شود و فورا همه ترافیک را به سمت backend ASP.NET Core application هدایت می کند. همه در خواست ها (حتی درخواست هایی که به Handler های سطح بالا مانند ASPX نگاشت شده اند) از IIS pipeline عبور می کنند و به پردازش اصلی ASP.NET Core هدایت می شوند. این گفته به این معنی است که نمی توانیم به آسانی ، ASP.NET Core را با فریم ورک های دیگر در یک directory ترکیب کنیم. در حالی که در روش های کلاسیک، این کار آسان و شدنی بود.

زمانی که IIS Site/Virtual نیاز به یک IIS Application Pool  برای اجرا شدن دارد، Application Pool باید بر روی No Managed Code تنظیم شود. زیرا  App Pool به عنوان یک proxy ایفای نقش می کند که درخواست ها را هدایت می کند و دیگر نیازی به یک نمونه از .NET runtime نیست.

وظیفه ی AspNetCoreModule این است که مطمئن شود برنامه ی شما به محض دریافت اولین درخواست، بارگذاری می شود و همچنین در صورت توقف ناگهانی برنامه، ، پردازش همچنان در حالت اجرا باقی می ماند. در این حالت ، رفتاری مشابه آن چه که در نسخه های کلاسیک می دیدیم، خواهید دید.

یک بار که برنامه اجرا شود، درخواست های Http ورودی به وسیله این ماژول مدیریت می شوند و سپس به برنامه ی ASP.NET Core هدایت خواهند شد.

بنابراین، درخواست ها از وب می آیند و در kernel mode http.sys driver که به IIS بر روی پورت اصلی (80) و یا پورت SSL (443) ختم می شود، قرار می گیرند. سپس درخواست به برنامه ASP.NET Core شما بر روی پورت HTTP  پیکربندی شده و سازگار با برنامه شما  هدایت می شود که پورت 80/443 نیست. در اصل، IIS به منزله یک reverse proxy عمل می کند که درخواست ها را به ASP.NET Core شما که در حال اجرا بر روی Kestrel Web server دیگر بر روی یک پورت دیگر است، هدایت می کند.

Kestrel درخواست را دریافت می کند و آن را به pipeline مربوط به میان افزار ASP.NET Core می فرستد که درخواست شما را مدیریت می کند و آن را به بخش منطقی برنامه شما پاس می دهد. خروجی HTTP دوباره به IIS فرستاده می شود که سپس پس از انجام این مراحل، دوباره بر روی اینترنت به HTTP client که درخواست را آغاز کرده بود، باز پس فرستاده می شود که می تواند یک مرورگر، یک کاربر با یک دستگاه موبایل و یا یک برنامه باشد.

AspNetCoreModule به وسیله ی فایل web.config که در روت برنامه وجود دارد، پیکربندی شده است  که شامل startup command (dotnet) و یک آرگومان (dll اصلی برنامه) که برای اجرای اولیه برنامه .NET Core شما استفاده می شوند. پیکربندی در فایل web.config ، ماژول موجود در پوشه روت پروژه شما  و همچنین DLL مورد نیاز برای اجرای برنامه را نیز فراهم می کند.

در زیر کدهای موجود در بخش web.config آورده شده اند:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!--
    Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
  -->
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*"
        modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet"
                arguments=".\AlbumViewerNetCore.dll" 
                stdoutLogEnabled="false" 
                stdoutLogFile=".\logs\stdout" 
                forwardWindowsAuthToken="false" />
  </system.webServer>
</configuration>

 

آیا به IIS نیاز داریم؟

همان طور که تا به حال نیز صحبت کرده ایم، به شما توصیه می کنیم هنگام اجرای ASP.NET Core بر روی Windows، از IIS به عنوان یک front end proxy استفاده کنید. علاوه بر آن، می توانیم برای دسترسی مستقیم به Kestrel از یک IP Address و یک پورت آزاد  استفاده کنیم.

اولین و مهم ترین نکته این است که اگر می خواهید چندین برنامه را بر روی یک سرور  با پورت مشترک    80 و 443  اجرا کنید، نمی توانید Kestrel را مستقیما اجرا کنید. Kestrel از مسیریابی host header پشتیبانی نمی کند، که برای اتصال چندین پورت بر روی یک IP address مورد نیاز است. بدون IIS (و یا http.sys) شما نمی توانید از Kestrel به تنهایی استفاده کنید.

AspNetCoreModule اجرا شده بر روی IIS ، مدیریت پردازش های ضروری را امکان پذیر می کند تا به این وسیله مطمئن شود برنامه شما با اولین درخواست فراخوانی ، بارگذاری می شود و در صورت برخورد به مشکل و یا توقف ناگهانی برنامه، دوباره می تواند شروع به کار کند.  

همچنین اجرای درخواست های SSL به صورت امن از طریق IIS با تنظیم مجوز ها و همچنین دادن اجازه مدیریت احراز هویت های SSL به IIS ، می تواند راه خوب و بهینه ای باشد. سپس درخواست های HTTP ای که از IIS هستند ،می توانند به آسانی یک درخواست HTTP را به برنامه شما بفرستند.  این گفته به این معناست که فقط یک front end IIS server نیاز به مجوز دهی برای انجام امور دارد، حتی اگر چندین سرور در حال ذخیره محتویات HTTP باشند.

IIS همچنین می تواند فایل های static شما را نیز میزبانی کند، داده های static را gzip compression کند، static file caching ، بازنویسی Url را نیز تحت پوشش خودش انجام بدهد. IIS در پردازش درخواست های non-application بهینه و موثر است، بنابراین استفاده از آن به صرفه است. شما می توانید مدیریت این گونه وظایف را به IIS بسپارید و سایر امور را به برنامه ASP.NET Core محول کنید.

سایر مطالبی که در ادامه می گوییم برای زمانی است که شما دارید عمل میزبانی را بر روی Windows انجام می دهید و می خواهید از IIS و AspNetCoreModule استفاده کنید.

اجرای IIS به عنوان یک Development Server

ما این سوال را چندین بار تا به حال دیده ایم که :

آیا ما می توانیم بر روی full IIS، برنامه ASP.NET Core خودمان را مانند ورژن های کلاسیک دیباگ کنیم؟

برای این که بتوانیم کمی این سوال را ساده تر پاسخ بدهیم می توانیم بگوییم که : اجرای IIS  در طول مراحل توسعه، ضرورتی ندارد. در گذشته تفاوت های زیادی بین full IIS و IIS Express وجود داشت ولی الان این تفاوت ها کم رنگ تر شده اند.

اگر چه، با ASP.NET Core نیازی به اجرای full IIS در طول مراحل توسعه نداریم. زیرا برنامه های ASP.NET Core در حقیقت در داخل IIS اجرا نمی شوند. اجرای این گونه موارد درداخل IIS ، هیچ مزیتی نسبت به این روش ندارد.

اجرا کردن IIS

دلیل این که شما نمی توانید فقط IIS را در محیط توسعه اجرا کنید این است که برنامه ی ASP.NET Core شما باید قبل از این که اجرا شود، Publish شود.  پوشه ی development همه موارد ضروری برای اجرای برنامه را نگهداری نمی کند. زمانی که ما پروژه تان را اجرا و یا دیباگ می کنید، برنامه ابتدا در یک مکان جداگانه  Publish  می شود و سپس از همان جا اجرا می شود. به همین خاطر، شما نمی توانید IIS را به عنوان یک گزینه برای Visual  Studio در نظر بگیرید.

اگر شما نیاز دارید تا حتما برنامه را با IIS اجرا کنید، ابتدا می توانید برنامه را در یک پوشه محلی Publish کنید و سپس آن محل را برای استفاده های بعدی در نظر بگیرید.

 

Publish کردن برنامه ASP.NET Core برای IIS

برای اجرا کردن یک برنامه با IIS ، ابتدا نیاز دارید تا آن را Publish کنید. به دو روش زیر می توانید این کار را انجام بدهید :

استفاده از dotnet publish

استفاده از ویژگی های Publish مربوط به برنامه Visual Studio

 

استفاده از dotnet publish

زمانی که از dotnet publish  استفاده می کنید، ابتدا برنامه شما را Build می کند و سپس یک نسخه ی مستقل و قابل اجرا از برنامه را بر روی یک محل جدید بر روی حافظه می سازد. شما یک پوشه خروجی مشخص می کنید که همه فایل های مربوط به Publish در آن قرار خواهند گرفت.

یک publish command معمولا به صورت زیر خواهد بود :

dotnet publish

      --framework netcoreapp1.0

      --output "c:\temp\AlbumViewerWeb"

      --configuration Release

این تکه کد ، برنامه را در مکان c:\temp\albumviewerWeb ،  Publish  می کند.

اگر شما این پوشه را باز کنید خواهید دید که فایل های اصلی برنامه به همراه سایر پکیج ها را خواهید دید :

میزبانی یک پوشه ی Publish به صورت Manual IIS

زمانی که  شما برنامه را Publish  می کنید و آن را بر روی سرور قرار می دهید، می توانیم IIS را به پوشه متصل کنیم.

حال می خواهیم یک  Application directory مجازی ایجاد کنیم .

دقت کنید که ما یک AspNetCore Application Pool ایجاد کرده ایم که .NET Runtime مخصوص به خودش را دارد که بر روی No Managed Code تنظیم شده است. و این موضوع ،همه مواردی است که ما نیاز داریم. حالا شما نیاز دارید تا مسیر را بر روی مسیر سایت و یا برنامه تان قرار بدهید و سپس از آن اجرا بگیرید.

Publish کردن از طریق Visual Studio

dotnet publish برای کپی کردن تمام یک پوشه به کار می رود، ولی این روش ، در حقیقت پروژه شما را بر روی یک وب سایت Publish  نمی کند.

برای این که بتوانید عملیات Publish را به صورت کامل برای برنامه های ASP.NET Core انجام بدهید، به دلیل وجود وابستگی های متعدد، نیاز خواهید داشت تا از MsDeploy استفاده کنید که یکی از ویژگی های Publish موجود در Visual Studio است.

برای این که بتوانید یک 'manual profile' در پروژه ASP.NET Core Web خود ایجاد کنید:

یک پوشه \Properties\PublishProfiles ایجاد کنید .

یک فایل <MyProfile>.pubxml ایجاد کنید .

شما می توانید .pubxml را از یک پوشه کپی کنید و به پروژه تان بیاورید و یا آن را خودتان ایجاد کنید. در زیر مثالی از یک پروفایل سازگار با IIS را مشاهده می کنید:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>	
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish>http://samples.west-wind.com/AlbumViewerCore/index.html</SiteUrlToLaunchAfterPublish>
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <PublishFramework>netcoreapp1.0</PublishFramework>
    <UsePowerShell>True</UsePowerShell>
    <EnableMSDeployAppOffline>True</EnableMSDeployAppOffline>
    <MSDeployServiceURL>https://publish.west-wind.com</MSDeployServiceURL>
    <DeployIisAppPath>samples site/albumviewercore</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>RemoteAgent</MSDeployPublishMethod>
    <EnableMSDeployBackup>False</EnableMSDeployBackup>
    <UserName>username</UserName>
    <_SavePWD>True</_SavePWD>
    <ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
    <AuthType>NTLM</AuthType>	
  </PropertyGroup>
</Project>

 

AuthType NTLM Fix

به کلید <AuthType>NTLM</AuthType> در خط انتهایی فایل توجه کنید. این کلید بسیار مهم است زیرا در صورتی که نباشد، عملیات publish انجام نخواهد شد. دقت کنید که حتما آن را استفاده کرده باشید.

زمانی که شما یک فایل .pubxml را ایجاد می کنید، می توانید پنجره زیر را ببینید :

 

 

در این مرحله شما می توانید برنامه خودتان را بر روی IIS و سپس بر روی یک سرور راه دور ، Publishکنید و به روزرسانی های مورد نظرتان را در آن اعمال کنید.

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید