نظرات مطالب
استفاده از pjax بجای ajax در ASP.NET MVC
مشکل همینجاست فکر کنم که از beginForm چه عادی چه Ajax ای استفاده میشه
در حالت Ajax که مشکل اساسی هست و چندتا چندتا INsert میشه و یه جورایی همینطور تو حلقه میمونه
از Html.beginForm استفاده میکنم رفرش میشه
از هیچکدوم استفاده نکنم نمیدونم چطوری اطلاعات صفحه رو به یه Action توی کنترلر با دکمه Submit ارسال کنم!
در حالت Ajax که مشکل اساسی هست و چندتا چندتا INsert میشه و یه جورایی همینطور تو حلقه میمونه
از Html.beginForm استفاده میکنم رفرش میشه
از هیچکدوم استفاده نکنم نمیدونم چطوری اطلاعات صفحه رو به یه Action توی کنترلر با دکمه Submit ارسال کنم!
اگر شما به سایتهای مدیریت کدی نظیر github مراجعه کنید و تعداد کاربران و یا پروژههای قرار گرفته بر روی آنها را در نظر بگیرید متوجه محبوبیت سیستم مدیریت کد git خواهید شد در مورد تفاوتهای سیستمهای CVS و DVCS در مقاله اول توضیحاتی داده شد و در مقاله بعد درباره نحوه ذخیره سازی اطلاعات که باعث افزایش سرعت چشمگیر در عملیات check-in و check-out میشود
در ضمن در git و در همه سیستمهای مدیریت کد امکان دستیابی به کدهای قبل وجود دارد و به طور کلی این یکی از اهداف سیستمهای مدریت کد است.
خود من هم یک برنامه نویس دات نت هستم اما دلیلی ندارد که مجبور باشیم هر آنچه که مایکروسافت ساخته را استفاده کنیم
من با هر دو سیستم TFS و Git کار کردم و به شخصه استفاده و راه اندازی آن را از TFS سادهتر میبینم چون تنها یکی از کاربردهای TFS مدیریت کد است بنابراین شما به طور نسبی با سیستم پیچیدهتری سرو کار خواهید داشت.
اما در نهایت نیاز شما به معماری مورد استفاده در مدیریت کدهای خود تعیین کننده است
اگر یک سیستم مدیریت کد توزیع شده لازم دارید بهترین انتخاب git است
موفق باشید
در ضمن در git و در همه سیستمهای مدیریت کد امکان دستیابی به کدهای قبل وجود دارد و به طور کلی این یکی از اهداف سیستمهای مدریت کد است.
خود من هم یک برنامه نویس دات نت هستم اما دلیلی ندارد که مجبور باشیم هر آنچه که مایکروسافت ساخته را استفاده کنیم
من با هر دو سیستم TFS و Git کار کردم و به شخصه استفاده و راه اندازی آن را از TFS سادهتر میبینم چون تنها یکی از کاربردهای TFS مدیریت کد است بنابراین شما به طور نسبی با سیستم پیچیدهتری سرو کار خواهید داشت.
اما در نهایت نیاز شما به معماری مورد استفاده در مدیریت کدهای خود تعیین کننده است
اگر یک سیستم مدیریت کد توزیع شده لازم دارید بهترین انتخاب git است
موفق باشید
Application Insights راهکار ارائه شده توسط Microsoft است که در سه بخش به ما کمک میکند تا سیستم لاگ مؤثر و کارآمدی داشته باشیم:
۱- متدهای پایه Log که به صورت دستی فراخوانی میشوند، مانند TrackEvent برای ثبت یک رویداد بیزینسی که این متدها فراتر از متدهای معمول loggerهای متداول هستند.
۲- به صورت خودکار، Application Insights خطاهای سیستم را لاگ نموده و همچنین در زمان کار کردن با Http Client، دیتابیس و سایر Dependencyها، میزان طول کشیدن آنها را به همراه آدرس Request یا متن Sql Command و سایر اطلاعات مفید را نیز ذخیره میکند که این خود منجر به جمع شدن دیتایی بسیار ارزشمند در سیستم میشود.
البته اگر یک Dependency به صورت خودکار شناسایی نشود، مانند Redis، شما میتوانید خودتان با متد TrackDependency اطلاعات آنرا به AppInsights بدهید.
۳- داشبورد App Insights در Azure این امکان را میدهد که به سریعترین شکل ممکن در لاگها جستجو نمود و برای مثال تمامی کارهای انجام شده توسط یک کاربر خاص را به صورت یکجا مشاهده و بررسی کرد.
فرضا اگر کاربر درخواست گرفتن خروجی Excel از لیست محصولات را داشته و این ۱ ثانیه طول کشیده، چقدر آن در انتظار دیتابیس بوده و ...
به علاوه از Power BI نیز میتوانید برای بیرون کشیدن نکات مهم استفاده کنید.
البته شاید App Insights برای کسانی که Azure Account نداشته باشند، مناسب به نظر نرسد، ولی اگر راهکاری برای ذخیره سازی On-Premise اطلاعات لاگ شده وجود داشته باشد چه؟ مثلا اطلاعات آن را در Elastic موجود در سرورهای شرکت، داخل ایران ذخیره نمود، بدون الزام به اینکه حتی آن سرور دسترسی به اینترنت داشته باشد.
بله، این امکان وجود دارد و با کمک Microsoft Diagnostics EventFlow میتوان اطلاعات App Insights را در هر جایی از جمله Elastic ذخیره نمود و بدین طریق از عمده مزایای App Insights بدون داشتن Azure Account بهره مند شد.
برای این منظور به شکل زیر عمل کنید: (آموزش برای ASP.NET Core 3.1 بوده، ولی برای سایر پروژهها نیز قابل استفاده است)
۱- ابتدا Application Insights را به پروژه خود اضافه کنید.بدین منظور لازم است Packageهای Microsoft.Extensions.Logging.ApplicationInsights و Microsoft.ApplicationInsights.AspNetCore را نصب کنید.
۲- در Program.cs بعد از
Host.CreateDefaultBuilder(args)
.ConfigureLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddApplicationInsights(); })
۳- اگر جایی قصد لاگ کردن یک Event را دارید، یا در مثال استفاده از Redis میخواهید اطلاعات زمان طول کشیدن رفت و برگشت به Redis را لاگ کنید یا یک try/catch دارید که در catch آن خطا را مجدد throw نمیکنید، ولی قصد لاگ کردن exception را دارید، ابتدا TelemetryClient را inject نموده و از متدهای آن مانند TrackException استفاده کنید.
توجه داشته باشید که اگر از ILogger ارائه شده توسط MS.Ext.Logging استفاده کنید نیز کار خواهد کرد.
۴- پکیج Microsoft.Diagnostics.EventFlow.Inputs.ApplicationInsights را در پروژه نصب کنید و سپس از بین Outputهای معرفی شده نیز یکی را انتخاب و پکیج آن را نیز نصب کنید. شما میتوانید دیتایی را که AppInsights به صورت خودکار جمع نموده را + دیتای ارائه شده توسط خودتان را به Elastic، Splunk و ... بفرستید.
ما در این مثال برای سادگی Std Out - Console Output را انتخاب میکنیم و پکیج Microsoft.Diagnostics.EventFlow.Outputs.StdOutput را نصب میکنیم.
۵- فایل eventFlowConfig.json را به پروژه اضافه کنید و موارد زیر را در آن قرار دهید:
{ "inputs": [ { "type": "ApplicationInsights" } ], "outputs": [ { "type": "StdOutput" // console output } ], "schemaVersion": "2016-08-11" }
۶- در Program.cs متد Main را به شکل زیر در بیاورید:
using (var pipeline = DiagnosticPipelineFactory.CreatePipeline("eventFlowConfig.json")) { CreateHostBuilder(args, pipeline) .Build() .Run(); }
public static IHostBuilder CreateHostBuilder(string[] args, DiagnosticPipeline pipeline) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services => services.AddSingleton<ITelemetryProcessorFactory>(sp => new EventFlowTelemetryProcessorFactory(pipeline)))
.ConfigureLogging(logginBuilder =>
{
logginBuilder.ClearProviders();
loggingBuilder.AddApplicationInsights();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
همه چیز آماده است. هم اکنون اگر Azure Account داشته باشید، میتوانید با دادن instrumentationKey در appsetting.json از داشبورد فوق العاده ApplicationInsights استفاده کنید و اگر نه هم در سرورهای داخلی خودتان Splunk و ... را راه اندازی و در فایل eventFlowConfig.json، در قسمت outputs، اطلاعات آدرس آنها را بدهید و لاگهای مفصل و کاربردی ای که به صورت خودکار جمع آوری شده را به همراه اطلاعاتی که خودتان دستی ارائه کرده اید، یکجا تحویل بگیرید.
لینک پروژه در GitHub که حاوی مثال Elastic است.
When we started the Google Code project hosting service in 2006, the world of project hosting was limited. We were worried about reliability and stagnation, so we took action by giving the open source community another option to choose from. Since then, we’ve seen a wide variety of better project hosting services such as GitHub and Bitbucket bloom. Many projects moved away from Google Code to those other systems. To meet developers where they are, we ourselves migrated nearly a thousand of our own open source projects from Google Code to GitHub.
- تنظیمات IoC Container آن (برنامهای که آزمایش شده و کار میکند) در اینجا هست. کدهای خودتان را با آن مقایسه کنید.
- آدرسی که کار میکند، یعنی جزو مسیریابی سیستم ثبت شدهاست.
- برای فعال سازی CORS این مراحل باید طی شوند:
در فایل WebApiConfig.cs، در ابتدای متد Register این کدها باید اضافه شوند:
در گردش کاری CORS، کلاینت قبل از ارسال درخواستهای delete، put و post، ابتدا درخواستی از نوع option را ارسال میکند تا وضعیت دسترسی را بررسی کند:
به علاوه در ابتدای کدهای سمت کلاینت هم این سطر باید اضافه شود:
- آدرسی که کار میکند، یعنی جزو مسیریابی سیستم ثبت شدهاست.
- برای فعال سازی CORS این مراحل باید طی شوند:
در فایل WebApiConfig.cs، در ابتدای متد Register این کدها باید اضافه شوند:
var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); config.MessageHandlers.Add(new PreflightRequestsHandler());
public class PreflightRequestsHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.Headers.Contains("Origin") && request.Method.Method == "OPTIONS") { var response = new HttpResponseMessage {StatusCode = HttpStatusCode.OK}; response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization"); response.Headers.Add("Access-Control-Allow-Methods", "*"); var tsc = new TaskCompletionSource<HttpResponseMessage>(); tsc.SetResult(response); return tsc.Task; } return base.SendAsync(request, cancellationToken); } }
jQuery.support.cors = true;
سیستمهای مدیریت ماژول یا باندل کنندههای جاوااسکریپتی، چندی است که دچار تنوع زیادی شدهاند و هر از گاهی، چهرههای جدیدی خود نمایی میکنند. اگر با انگولار 2 آشنا باشید قطعا با SystemJs که یکی دیگر از این گونه باندل کننده هاست آشنایید. در این سری قصد داریم که با یک باندل کنندهی تقریبا همه کاره با نام webpack آشنا شویم.
قدم دوم نصب webpack میباشد. برای نصب وب پک دو راه وجود دارد:
اگر دقت کنید اسکریپتی با نام bundle.js در فایل html رجوع داده شده است که در پروژه وجود خارجی ندارد و قصد این است که این فایل را با استفاده از وب پک تولید کنیم.
حال با استفاده از دستور npm run webpack ./main.js bundle.js ، وب پک فراخوانی شده و تک فایل main.js را باندل میکند.
مقدمه و توضیحی بر اینکه چه لزومی بر باندل کنندههای جاوااسکریپتی هست؟
زمانیکه جاوا اسکریپت پا به عرصهی وجود گذاشت، در توسعهی برنامههای کلاینت، از سیستمهای بیلد استفادهای نمیشد و شاید بتوان سادهترین دلیل آن را عدم احتیاج جاوااسکریپت به کامپایل دانست. ولی با گذشت زمان و عوض شدن چهرهی برنامههای سمت کلاینت و بزرگتر شدن آنها، برنامه نویسان با مشکلاتی از قبیل نگه داری و امنیت، در برنامههای بزرگ رو به رو بودند.
در پاسخ به بزرگ شدن پروژهها قطعا شما این پیشنهاد را خواهید داد که بایستی برنامه را به قسمتها و یا ماژولهای کوچکتری بشکنیم، تا هم نگه داری از آن سادهتر شود و هم احتمال بروز خطا در حین انجام پروژه کاهش یابد. اما باید به یاد داشت که این قسمتهای کوچک شده به معنای یک تگ اسکریپت جدا در صفحات وب برنامه میباشند و این مساله به این معنا خواهد بود که برای هر یک از آنها، مرورگر بایستی به میزبان، درخواستی را ارسال کرده و فایلها را جداگانه دریافت کند. قطعا پاسخ به این مشکل دوباره چسباندن این ماژولها به یکدیگر است تا مرورگر فقط یک درخواست را برای این فایلها ارسال کند. این مسئله همچنین برای فایلهای css و تصاویر نیز صادق میباشد.
دومین مشکلی که با ماژول سازی برنامه با آن روبه رو میشویم، بالا رفتن حجم کد و درنتیجه بالا رفتن ترافیک مصرفی خواهد بود که این مسئله نیز بایستی توسط یک Minifier حل شود. مشکل بعدی، وابستگی ماژولها به یکدیگر است .در صورتی که در اضافه کردن یک ماژول به وابستگیهای آن دقت نداشته باشیم، باعث بروز خطا در برنامه میشویم. با استفاده از یک باندلر میتوانیم وابستگیهای هر ماژول را تعریف کنیم تا این مسئله نیز حل شود.
آخرین مسالهای که به ذهن میآید نیز میتوان قابلیتهای جدید ES6 را نام برد که به صورت سراسری در تمامی مرورگرها ممکن است هنوز قابل استفاده نباشند و شما به عنوان برنامه نویس قصد بهره بردن از آنها را داشته باشید. درنتیجه راهکار، استفاده از یک ترانسپایلر است که میتوان از معروفترین آنها تایپ اسکریپت و babel را نام برد .
راهکارهای مختلف برای حل مشکلات ذکر شده
در صورتی که با فریمورکهای سمت سرور آشنایی داشته باشید، حتما با سیستمهای باندل کننده و Minify کنندهی آنها برخورد داشته اید. به طور مثال فریمورک Asp.Net Mvc دارای یک باندل کنندهی توکار است که مشکل بسته بندی کردن کل ماژولها و همچنین Minify کردن آنها را حل میکند. ولی تا آخرین اطلاعی که دارم، مشکل وابستگی ماژولها به جز اینکه برنامه نویس به صورت دستی ترتیب اضافه شدن را رعایت نماید، قابل حل نیست. همچنین در اینجا استفاده از یک ترانسپایلر نیز مقدور نمیباشد.
راه حل دیگر استفاده از Task Runnerهای جاوا اسکریپتی مانند گرانت و گالپ میباشد که تمامی مسائلی که پیشتر ذکر شد، به وسیلهی آنها قابل حل است؛ به جز مسئلهی وابستگی ماژولها به یکدیگر که بایستی به صورت دستی توسط برنامه نویس ترتیب آنها رعایت شود یا از فریمورک هایی مانند browserify و ... استفاده شود.
راه حل webpack
تفاوت وب پک با TaskRunnerهای جاوا اسکریپتی را میتوان در اینجا بیان کرد که وب پک در انجام یک وظیفه تخصص وافری دارد و آن وظیفه نیز پردازش فایلهای ورودی و خروجی داده شده به آن است که با استفاده از کامپوننتهایی که با نام loader از آن نام میبرد، این وظیفه را انجام میدهد. با استفاده از این لودرها شما نتیجهای را که از یک TaskRunner انتظار دارید، خواهید گرفت؛ مانند ترنسپایل کردن ماژولها، بسته بندی ماژولها، Minify کردن آنها و در نهایت قابلیتی که معمولا در Task Runnerها موجود نیست و وب پک امکان انجام آن را دارد، ترکیب فایلهای Css با فایلهای جاوا اسکریپت برنامه است. این کار برای تصاویر و فونتهای برنامه نیز قابل انجام است.
پیش فرضهای کار با webpack
دو پیش فرض مهم در شروع به کار با وب پک از این قرارند:
1. وب پک برای نصب Assetهای سمت کلاینت شما از NPM استفاده میکند و انتظار دارد که شما نیز این پکیج منیجر بهره ببرید و به طور مثال از bower استفاده نکنید.
2.استفاده از یک سیستم ماژولار ( اینکه از کدام یک استفاده میکنید مهم نیست Commonjs ، amd ، es6 و...)
نصب webpack و شروع کار
webpack یکی از صدها ماژولهای نوشته شدهی با استفاده از پلتفرم nodejs میباشد. پس اول از همه چیز در صورتیکه nodejs بر روی سیستم شما نصب نیست، آن را دریافت و نصب کنید.
قبل از شروع به کار بهتر است که یک محیط کار تمیز ( یک فولدر خالی) را آماده کنید و سپس با اجرای دستور npm init، یک بستر برای کار با npm را داشته باشیم. میتوانید به صورت دستی نیز یک فایل package.json را اضافه کنید و گزینههای مدنظرتان را به آن اضافه کنید.
من با اجرای این دستور و جواب دادن به سوالاتش یک خروجی فایل package.json با این محتوا را ایجاد کردم :
{ "name": "dntwebpack", "version": "1.0.0", "description": "a webpack tutorial", "main": "main.js", "scripts": { }, "author": "mehdi", "license": "MIT" }
1. نصب وب پک به صورت گلوبال ( سراسری ) با استفاده از دستور :npm install -g webpack ، با اجرای این دستور قابلیت استفاده از وب پک را در همه جا با استفاده از خط فرمان، خواهید داشت.
2. ایراد روش اول این است که ممکن است در آینده بخواهید در پروژههای گوناگون از دو نسخهی متفاوت وب پک استفاده کنید و به خاطر نسخهای که به طور سراسری نصب شده است به مشکل بر بخورید. پس با استفاده از دستور npm install -D webpack یا npm install --save-dev webpack وب پک را به صورت محلی برای پروژه نصب میکنیم ( کاربرد پرچم D- یا --save-dev این است که وب پک در قسمت وابستگیهایی که فقط جهت توسعهی پروژه هستند، در فایل package.json اضافه میشود).
در ادامه در محیط کاری که ایجاد کردیم، دو فایل دیگر را ایجاد میکنیم. اولی یک فایل سادهی html جهت اینکه اسکریپتهای پروژه را به آن اضافه کنیم و دیگری یک فایل اسکریپت جهت اینکه آن را به وب پک بدهیم.
فایل html را index.html نام گذاری کردم و اسکریپت سمپل را نیز main.js. محتوای هر دوفایل به این صورت میباشد:
<html> <!-- index.html --> <head> first part of webpack tut! </head> <body> <h1>webpack is awesome !</h1> <script src="bundle.js"></script> </body> </html>
//main.js //start of the journey with webpack console.log(`i'm bundled by webpack`);
حالا نوبت به این میرسد که تک فایل main.js را به وب پک بدهیم.
در صورتی که وب پک را به صورت سراسری نصب کرده باشید، این کار ساده است. در خط فرمان با فراخوانی وب پک با دستور webpack ./main.js bundle.js
فایل bundle.js را تولید میکنیم.
فایل bundle.js را تولید میکنیم.
در صورتی که وب پک به صورت محلی در پروژه نصب شده باشد، فایل package.json را باز کرده و در قسمت scripts، یک ورودی جدید را به اسم webpack به همراه فرمان مورد نظر، به آن میدهیم. محتوای فایل package.json پس از این کار به صورت زیر خواهد بود:
{ "name": "dntwebpack", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" ,"webpack":"webpack" }, "author": "mehdi", "license": "ISC", "devDependencies": { "webpack": "^1.13.1" } }
در صورتی که اجرای دستور بالا موفقیت آمیز باشد، پاسخی مشابه به زیر را باید دریافت کنید:
در قسمت بعدی با تنظیمات پیشرفتهتر و loaderهای وب پک آشنا میشویم .
فایلهای پروژه dntwebpack.zip (جهت اجرای آنی احتیاج به نصب وبپک را دارید که این کار با استفاده از دستور npm install در فولدر پروژه قابل انجام است).
نظرات مطالب
ASP.NET MVC #11
- صفحه تعویض پسورد کاربر، چک باکس IsAdmin را ندارد. اما چون Model کامل کاربر در پشت صحنه آپدیت میشود، اگر با جعل صفحه یا درخواست ارسالی به سرور، اطلاعات IsAdmin هم ارسال شود، آنگاه Model binder که با model کامل User کار میکند، اطلاعات IsAdmin اضافی را هم دریافت کرده و پردازش میکند. بنابراین به نحوی باید سطح کلی در معرض عموم قرارگیری model را کاهش داد که روشهای آن هم ذکر شد.
- در مورد نحوه انجام این حمله توضیحی نخواهم داد... فقط بدونید که سایت github چند وقت قبل بر همین اساس هک شد و سر و صدای زیادی هم به پا کرد: (^)
- در مورد نحوه انجام این حمله توضیحی نخواهم داد... فقط بدونید که سایت github چند وقت قبل بر همین اساس هک شد و سر و صدای زیادی هم به پا کرد: (^)