نظرات مطالب
راه اندازی StimulSoft Report در ASP.NET MVC
با سلام؛ از روش مورد اشاره مقاله استفاده کردم. کد فایل report.chtml به شکل زیر تغییر یافت :
 @Html.Stimulsoft().StiMvcViewer("MVCViewer1", new StiMvcViewerOptions()
           {
               Actions = new StiMvcViewerOptions.ActionOptions()
               {
                   GetReportSnapshot =
                   Url.Action(
                       MVC.TableProduct.Report.ActionNames.CustomReportSnapshot,
                   MVC.TableProduct.Report.Name, new { area = MVC.TableProduct.Name }, "http"),
                   ViewerEvent =
                   Url.Action(
                       MVC.TableProduct.Report.ActionNames.CustomViewerEvent,
                       MVC.TableProduct.Report.Name, new { area = MVC.TableProduct.Name }, "http"),
                   PrintReport =
                   Url.Action(
                       MVC.TableProduct.Report.ActionNames.CustomPrintReport,
                       MVC.TableProduct.Report.Name, new { area = MVC.TableProduct.Name },"http"),
               },
               Server = new StiMvcViewerOptions.ServerOptions()
               {
                   PassFormValues = true,
                   GlobalReportCache = false,
                   Controller = MVC.TableProduct.Report.Name

               },
               Exports = new StiMvcViewerOptions.ExportOptions()
               {
                   ShowExportToPdf = true,
                   ShowExportToCsv = true
               },
               Toolbar = new StiMvcViewerOptions.ToolbarOptions()
               {
                   ShowDesignButton = false,
                   ShowEditorButton = false,
                   ShowParametersButton = false,
                   ShowViewModeButton = true
               },

               Localization = "~/Content/Stimulsoft/Localization/fa.xml",
               Width = Unit.Percentage(100),
               Theme = StiTheme.Office2013,

           })
در این کد مسیر Action‌ها به درستی ایجاد شده است. برای مثال برای متد getReportSnapshot  آدرس زیر تولید شده است :
http://localhost:14425/tableproduct/customreportsnapshot 
این آدرس کاملا صحیح بوده و با PostMan قابل فراخوانی است. اما همچنان مشکل فوق پابرجا بوده و گزارش نشان داده نشده و هیچ یک از متد‌های پرینت فراخوانی نمی‌شوند.
نظرات مطالب
بررسی نحوه‌ی راه اندازی پروژه‌ی Decision
اگر در هنگام اجرای دستور زیر 
PM> Update-Database -Verbose -ConnectionStringName "DefaultConnection" -StartUpProjectName "Decision.Web"

با  FILESTREAM feature is disabled    مواجه شدید . 
گزارش خطا :
PM> Update-Database -Verbose -ConnectionStringName "DefaultConnection" -StartUpProjectName "Decision.Web"

EXEC sp_configure filestream_access_level, 2
Configuration option 'filestream access level' changed from 2 to 2. Run the RECONFIGURE statement to install.
RECONFIGURE
alter database DecisionDb Add FileGroup FileGroupApplicant contains FileStream
System.Data.SqlClient.SqlException (0x80131904): FILESTREAM feature is disabled.
FILESTREAM feature is disabled.
که بنده نیز در هنگام اجرای پروژه با آن مواجه شدم به لینک‌های زیر مراجعه کنید تا راهنمایی لازم را در این مورد انجام دهد:
«آشنایی با قابلیت FileStream اس کیوال سرور 2008 - قسمت دوم»
 https://msdn.microsoft.com/en-us/library/cc645923.aspx   
نظرات مطالب
تولید SiteMap استاندارد و ایجاد یک ActionResult اختصاصی برای Return کردن SiteMap تولید شده
- قسمت‌های مختلف را کوئری می‌گیرید (یعنی به صورت پویا تولید می‌شود و نه اینکه جایی ثبت شوند)، union می‌کنید (چندین قسمت هست؟ مهم نیست. لیست‌های تمام آن‌ها باید به فرمت Sitemap نگاشت شده و یکی شوند) و نهایتا به صورت یک خروجی واحد ارائه می‌دهید. بحث لینک‌های تکراری در اینجا مهم نیست (و مرتبط است به محتوای تکراری با آدرس‌های مختلف در یک سایت و نه لینک‌های سایت‌مپ). ممکن هست یک سایت در طول هفته اصلا رکورد جدیدی نداشته باشد. موتور جستجوگری که به آن می‌رسد یک سری لینک مشخص و تکراری را هر روز دریافت می‌کند و مدیریت ثبت آن‌ها هم کاملا مشخص است و خودشان تکراری ثبت نمی‌کنند.
برای درک بهتر نحوه‌ی ایندکس شدن sitemap نیاز هست به Google Webmaster Tools وب سایت خودتان را اضافه کنید و سپس token آن‌را در سایت معرفی کنید. پس از مدتی می‌توانید گزارش بگیرید که دقیقا چه مواردی را ثبت کرده‌است و به چه نحوی.
- ضمنا امکان تعریف Sitemap index هم وجود دارد (جهت تعریف چندین سایت‌مپ در سایت). اطلاعات بیشتر در پروتکل آن آماده‌است. ولی در کل فرمت تولید آن سایت‌مپ‌ها هم به همین نحو استاندارد معرفی شده‌است. فقط در این حالت خاص که سایت‌مپ در ریشه‌ی سایت قرار نمی‌گیرد و یا به آن اشاره نمی‌کند، محدود هستید به معرفی لینک‌های همان پوشه و یا بازه.
نظرات مطالب
OpenCVSharp #6
- وجود Thread Sleep با مقداری که در مطلب فوق عنوان شده، ضروری هست. از این جهت که اساسا رابط کاربری معمولی ویندوز، قابلیت پردازش تعداد عظیمی از پیام‌های رسیده را ندارد و باید در این بین به آن فرصت داد. بحث DirectShow مجموعه‌ی Direct-X متفاوت است و طراحی اختصاصی آن برای یک چنین کارهایی است. اما در اینجا نمی‌توانید UI معمولی را با سیلی از داده‌ها و پیام‌های به روز رسانی، مدفون کنید.
- استفاده از متد capture.QueryFrame().ToBitmap اشتباه هست. از این جهت که خروجی capture.QueryFrame می‌تواند نال باشد. بنابراین این تبدیل را باید در داخل حلقه انجام دهید و نه در زمانیکه قصد دارید تصویری را دریافت کنید. شرط موجود در حلقه (مانند مثال اصلی مطلب)، بررسی نال نبودن این فریم دریافتی است. بنابراین اگر نال باشد، حلقه پایان خواهد یافت.
- همانطور که در متن عنوان شد، متد workerProgressChanged در ترد اصلی یا همان ترد UI اجرا می‌شود. بنابراین فراخوانی pictureBoxIpl1.Invoke غیر ضروری است و سربار بی‌جهتی را به سیستم تحمیل می‌کند.
به صورت خلاصه در حین استفاده‌ی از BackgroundWorker:
- متد رخداد گردان DoWork بر روی ThreadPool اجرا می‌شود (ترد آن با ترد UI یکی نیست)
- متد‌های رخدادگردان گزارش پیشرفت کار و اتمام کار، بر روی ترد UI اجرا می‌شوند. بنابراین امکان دسترسی به عناصر UI در این متدها، بدون مشکلی وجود دارد.
نظرات مطالب
مدیریت هماهنگ شماره نگارش اسمبلی در چندین پروژه‌ی ویژوال استودیو
یک اسمبلی در پروژه، به خودی خود فاقد مفهوم است و در قالب نگارش کلی برنامه مفهوم پیدا می‌کند.
فرض کنید برنامه شما از یک فایل exe به همراه دو اسمبلی A و B، تشکیل شده‌است. اسمبلی A، نگارش یک دارد. اسمبلی B نگارش 2 و کل برنامه در نگارش 2.5 است. خطایی به شما گزارش شده‌است که در آن استثنای حاصل، از نگارش یک اسمبلی A صادر شده‌است. این مشکل که در نتیجه‌ی در یافت پردازش اشتباهی از اسمبلی B بوده و در نگارش 2 آن برطرف شده، به صورت خودکار با ارتقاء به آخرین نگارش برنامه، برطرف می‌شود.
سؤال: آیا اکنون می‌توانید تشخیص دهید کاربر از آخرین نگارش محصول شما استفاده می‌کند؟ نگارش یک A، آخرین نگارش آن است و اما برنامه در نگارش 2.5 قرار دارد. کاربر هم مدتی است که برنامه را به روز نکرده‌است.
یک سیستم از همکاری اجزای مختلف آن مفهوم پیدا می‌کند.
برای مطالعه بیشتر: «Best Practices for .NET Assembly Versioning». عبارت «ensuring all of the various assemblies in the solution share the same version» حداقل دوبار در آن تکرار شده‌است.
نظرات مطالب
خودکار کردن تعاریف DbSetها در EF Code first
با سلام
چندوقتی هست که دارم از این روش برای برنامه هام استفاده میکنم و هیچ مشکلی نداشتم تا اینکه دیشب با یک مشکل عجیب برخورد کردم و مشکل این بود که زمان ساخت جداول به Property که به صورت NotMaped در کلاس Base تعریف کرده بودم ایراد گرفت.پس از بررسی که انجام دادم متوجه شدم که ترتیب Map کردن Entity‌ها باعث این مشکل میشه.
http://entityframework.codeplex.com/workitem/481 
این لینک مشکلی که گزارش شده، راه حلی که نوشه شده این که ترتیب Map کردن کلاس‌ها باید تغییر کند.این درحالی است که در این روش هیچ ترتیبی در نظر گرفته نمیشه و براساس خواندن کلاس‌ها از اسمبلی ساخته میشه.
برای رفع این مشکل اومدم و یک ویژگی ترتیب به کلاسهایی که میدونستم ترتیبشون مهم هست اضافه کردم و زمان خواندن کلاس‌ها از اسمبلی مورد نظر اونها مرتب کردم و مشکل حل شد.
آیا راه حل بهتری وجود داره یا نه ؟
var entityTypes = modelAssembly.GetTypes()
                                    .Where(type => type.Namespace != null
                                        && (type.Namespace.StartsWith(domainNamespace)
                                            && type.CustomAttributes.All(c => c.AttributeType != typeof(ComplexTypeAttribute))                                            
                                            && !type.IsAbstract && !type.IsEnum)
                                        )
                                    .OrderBy(c => c.CustomAttributes.Any(
                                        x => x.AttributeType == typeof (EntityOrderAttribute)) ? c.GetCustomAttribute<EntityOrderAttribute>().OrderNumber : 100).ToList();

مطالب
ساخت گزارش Code coverage مربوط به تست‌ها
اگر برای پروژه‌های خود تست نویسی انجام می‌دهید، یکی از موارد مهم، Code coverage مربوط به تست‌ها می‌باشد که نشان می‌دهد چند درصد از کدهای شما تست شده، کدام قسمت از کد، تست نشده‌است و ... .
در این مطلب نحوه‌ی استفاده از ReportGenerator را برای ایجاد گزارش مربوط به Code coverage، ارائه می‌دهیم. ReportGenerator دیتاهای تولید شده‌ی توسط coverlet, OpenCover, dotCover, Visual Studio, NCover, Cobertura, JaCoCo, Clover و ... را به یک گزارش قابل درک در فرمت‌های Html, Coberura و CSV تبدیل می‌کند. در  این مطلب چند موردتست نویسی با xUnit در Asp.Net Core  را نوشته‌ام و اکنون می‌خواهیم برای تست‌های نوشته شده، Code coverage آنها را بدست آوریم.
در کد زیر، سه تست برای متد AverageUsersAge نوشته شده است:
[Fact]
public async Task AverageUsersAge_When_Repository_Return_Null_Then_Zero_Should_Be_Returned()
{
    _userRepository.Setup(a => a.GetAllUsers())
        .ReturnsAsync((List<User>)null);
    var result = await _userService.AverageUsersAge();
    result.Should().Be(0);
}
[Fact]
public async Task AverageUsersAge_When_Repository_Return_Empty_Then_Zero_Should_Be_Returned()
{
    _userRepository.Setup(a => a.GetAllUsers())
        .ReturnsAsync(new List<User>());
    var result = await _userService.AverageUsersAge();
    result.Should().Be(0);
}
[Fact]
public async Task AverageUsersAge_When_Repository_Return_List_Of_Users_Then_Average_Of_Age_Should_Be_Retunred()
{

    _userRepository.Setup(a => a.GetAllUsers())
        .ReturnsAsync(UserMockData.People);
    var result = await _userService.AverageUsersAge();
    var expected = (UserMockData.AdultUser.Age + UserMockData.ChildUser.Age + UserMockData.InfantUser.Age) / 3;
    result.Should().Be(expected);
}
اکنون اگر بخواهیم Code coverage مربوط به این تست‌ها را مشاهده کنیم، ابتدا باید پکیج coverlet.collector  را در پروژه‌ی تست نصب کنیم. سپس باید دستور زیر را برای نصب ReportGenerator اجرا کنید؛ درون powershell:
dotnet tool install -g dotnet-reportgenerator-globaltool
اکنون میتوانیم Code coverage تست‌ها را تولید کنیم و با استفاده از ReportGenerator، آن‌را به قالب HTML تبدیل کنیم. اگر به مسیر پروژه تست خود بروید و دستور زیر را وارد کنید:
dotnet test --collect:"XPlat Code Coverage"
در پروژه‌ی تست شما، یک پوشه به نام TestResults ایجاد می‌شود و همچنین یک فایل xml با عنوان coverage.cobertura ایجاد شده‌است که نتیجه‌ی Code coverage مربوط به تست‌های شما در آن قرار دارد. 
اکنون می‌توانید با استفاده از ReportGenerator گزارش تست‌های خود را از فایل ایجاد شده، تهیه کنید. برای این کار باید دستور زیر را در مسیر پروژه تست، در powershell  وارد کنید:
reportgenerator -reports:"C:\Users\Farhad\source\repos\xUnitExample\xUnitExample.Tests\TestResults\*\coverage.cobertura.xml" -targetdir:"coveragereport" -reporttypes:Html
در پارامتر reports باید مسیر فایل xml ایجاد شده مربوط به Code coverage را قرار دهید (با هر بار اجرای دستور "dotnet test --collect:"XPlat Code Coverage یک فایل xml جدید ایجاد می‌شود و ممکن است در سیستم شما مقدار GUID ایجاد شده، تفاوت داشته باشد). 
درون پوشه TestResults یک پوشه دیگر قرار دارد که نام آن پوشه، یک GUID می‎‌باشد و به همین دلیل به جای استفاده از GUID از * استفاده کرده‌ایم.
 اگر دستور بالا را اجرا کنید باید خروجی زیر را مشاهده کنید:
2021-11-18T14:05:02: Arguments
2021-11-18T14:05:02:  -reports:C:\Users\Farhad\source\repos\xUnitExample\xUnitExample.Tests\TestResults\*\coverage.cobertura.xml
2021-11-18T14:05:02:  -targetdir:coveragereport
2021-11-18T14:05:02:  -reporttypes:Html
2021-11-18T14:05:02: Writing report file 'coveragereport\index.html'
2021-11-18T14:05:02: Report generation took 0.3 seconds
اکنون اگر در مسیری که دستور بالا را اجرا کردید بروید، یک پوشه به نام coveragereport مشاهده می‌کنید که یک فایل index.html دارد و اگر آنرا در مرورگر مشاهده کنید، Code coverage مربوط به تست‌های نوشته شده را مشاهده میکنید:


در عکس ارسال شده، تست‌های نوشته شده برای تمامی لایه‌ها به صورت جدا ایجاد شده‌است.
تست مربوط به UserService:

در عکس بالا قسمت‌هایی که تست شده‌اند، با رنگ سبز مشخص می‌شود و اگر قسمتی از کد تست نشده باشد، با رنگ قرمز مشخص می‌شود. 

برای مثال در عکس زیر مشخص شده‌است که برای فایل ApplicationConfiguration هیچ تستی نوشته نشده‌است.


اگر از CICD استفاده میکنید، می‌توانید در قسمت CI پروژه، هربار دستورات بالا را اجرا کنید و Code coverage مربوط به هر Build را به صورت جداگانه در کنار فایل‌های آپلود شده داشته باشد.
نکته: برای اجرای دستورات بالا و ساخت گزارش باید ورژن SDK نصب شده بر روی سیستم شما برابر 2.2.401 یا بیشتر باشد و ورژن Microsoft.NET.Test.Sdk برابر 16.5.0 یا بیشتر باشد.

مطالب
return File در ASP.NET MVC و نام‌های یونیکد
ابتدا نیاز است سورس فایل FileResult.cs را یکبار بررسی کنید. نکته جالبی که در آن وجود دارد نحوه ارسال نام فایل به مرورگر است که با پیاده سازی RFC 2183 و RFC 2231 انجام شده است. این خروجی‌‌های مبتنی بر RFCهای یاد شده، با تمام مرورگرهای جدید مانند کروم و فایرفاکس بدون مشکل کار می‌کنند. بنابراین اگر استفاده کنندگان از برنامه ASP.NET MVC شما از مرورگری مانند IE8 استفاده نمی‌کنند، نیازی به مطالعه ادامه بحث نخواهید داشت!
اما ... IE8 یک چنین درک و قابلیت پردازشی را ندارد. به همین جهت زمانیکه از return File در ASP.NET MVC استفاده شود و مرورگر نیز IE 8 باشد، نام یونیکد خروجی نهایی دریافتی توسط کاربر، یک سری حروف hex بی‌مفهوم خواهد بود.


نحوه رفع مشکل با IE

مطابق کدهای ذیل نیاز است filename را توسط متد Server.UrlPathEncode بازگشت دهیم؛ تا IE 8 بتواند آن‌را تفسیر کرده و درست نمایش دهد:
                var fileName = Path.GetFileName(filePath);
                if (Request.Browser.Browser == "IE")
                {
                    string attachment = string.Format("attachment; filename=\"{0}\"", Server.UrlPathEncode(fileName));
                    Response.AddHeader("Content-Disposition", attachment);
                }
                return File(filePath, "application/octet-stream", fileName);
در اینجا عملا دو هدر Content-Disposition وجود خواهد داشت و IE8 اولین مورد را پردازش می‌کند. اما مرورگرهای جدید این مورد را به صورت یک حمله گزارش می‌دهند و پردازش نخواهند کرد! به همین جهت بررسی شده است که اگر مرورگر IE بود ... آنگاه این تغییر اعمال شود.
البته روش دیگر، بازنویسی FileResult و یا تهیه یک FileResult سفارشی است.
مطالب
قسمت دوم : ساختار Solution در هنگام استفاده از Telerik Reporting
در این قسمت به بررسی مجدد یک نکته یا Best Practice در حین کار با Telerik Reporting می‌پردازیم.همانطور که گفته شد روش توصیه شده جهت استفاده از Telerik Reporting ، ساخت یک پروژه Class Library و قرار دادن گزارشات در آن می‌باشد.در ادامه می‌توان پروژه  Class Library ساخته شده را به هر تعداد پروژه ویندوزی و یا وب متصل کرد و گزارشات ساخته شده را به راحتی در محیط‌های مختلف نمایش داد.در تصویر زیر ساختار یک پروژه را بر اساس مباحث گفته شده مشاهده می‌کنید:


•  MyReportLib: پروژه Class Library شامل گزارشات Telerik Reporting می‌باشد.در اینجا پروژه فقط یک گزارش با نام "Report1.cs" دارد که در تصویر مشاهده می‌کنید.
•  MyWebApplication: یک پروژه از نوع Asp.net می‌باشد که گزارشات ساخته شده را می‌توان در آن به کاربر نمایش داد(در قالب صفحات HTML). توجه داشته باشید که این پروژه یک Reference به پروژه Class Library حاوی گزارشات دارد.
•  MyWindowsApplication: یک پروژه از نوع Windows Application است که برای نمایش گزارشات ساخته شده در محیط ویندوز می‌توان از آن استفاده کرد.توجه داشته باشید که این پروژه هم برای نمایش گزارشات ساخته شده یک Reference به پروژه Class Library دارد.
 
مطالب
JSLint.VS

JSLint.VS افزونه‌ای است رایگان برای VS.Net2005/2008 جهت بررسی ساده‌تر مشکلات دستوری در فایل‌های JavaScript یک پروژه.


اکنون بجای اینکه در مرورگر به دنبال خطاهای گزارش شده بگردیم، می‌توان پیش از بررسی نهایی آن‌ها، در VS.Net‌ مشکلات ممکن را یافته و برطرف ساخت.
JSLint.VS به منوی کلیک راست بر روی یک فایل js اضافه می‌شود و یا در حالت انتخاب قطعه‌ای کد و سپس کلیک راست و بررسی مشکلات موجود و یا در حالت یکپارچه با امکانات build پروژه قابل استفاده است (برای یکپارچه سازی با Build باید به منوی Tools قسمت JSLint.VS options مراجعه کرد و سپس گزینه build را درصفحه ظاهر شده تیک زد).



پس از دریافت آن، محتویات پوشه bin آن‌را در مسیر زیر کپی نمائید:
%My Documents%/Visual Studio 2008/Addins
Or
%My Documents%/Visual Studio 2005/Addins