مطالب
CoffeeScript #9

اصطلاحات عمومی CoffeeScript

Multiple arguments

همانطوری که در قسمت قبل در تابع Math.max مشاهده کردید، با استفاده از ... آرایه را به عنوان آرگومان چندگانه به تابع max ارسال کردیم. در پشت صحنه CoffeeScript برای اطمینان از ارسال کامل آرایه به تابع max، برای فراخوانی از تابع ()apply استفاده می‌کند. ما نیز می‌توانیم از این ویژگی در جای دیگری استفاده کنیم.

Log =
  log: ->
    console?.log(arguments...)
نتیجه‌ی کامپایل آن می‌شود:
var Log;

Log = {
  log: function() {
    return typeof console !== "undefined" && console !== null ? console.log.apply(console, arguments) : void 0;
  }
};
و یا می‌توان قبل از ارسال آرگومان‌ها در آنها تغییر ایجاد کرد.
Log =
  logPrefix: "(App)"

  log: (args...) ->
    args.unshift(@logPrefix) if @logPrefix
    console?.log(args...)
نتیجه‌ی کامپایل آن می‌شود:
var Log,
  slice = [].slice;

Log = {
  logPrefix: "(App)",
  log: function() {
    var args;
    args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
    if (this.logPrefix) {
      args.unshift(this.logPrefix);
    }
    return typeof console !== "undefined" && console !== null ? console.log.apply(console, args) : void 0;
  }
};
همانطور که مشاهده می‌کنید آرگومان‌های ارسالی به تابع log پس از چک شدن متغیر logPrefix و در صورت داشتن مقدار توسط تابع unshift به ابتدای آنها اضافه می‌شود.

And/Or

طبق ساختار syntax ایی که در قسمت‌های قبل با آن آشنا شدیم، or به جای || و and به جای && استفاده شده و سبب خوانایی بیشتر کد نوشته می‌شوند؛ در صورتیکه هر دو روش نتایج یکسانی را تولید می‌کنند.

همچنین به جای استفاده از == از is و برای =! از isnt استفاده می‌شود.

string = "migrating coconuts"
string == string # true
string is string # true
یکی از ویژگی‌های فوق العاده خوب که به CoffeeScript افزوده شده 'or equals' است که با الگو گرفتن از Ruby پیاده سازی شده است.
hash or= {}
نتیجه‌ی کامپایل آن می‌شود:
hash || (hash = {});
در اینجا در صورتیکه ارزیابی hash برابر false شود، مقدار آن برابر یک شیء خالی می‌شود. نکته‌ی مهمی که وجود دارد در صورتیکه hash مقداری برابر 0 ، "" و یا null داشته باشد، ارزیابی آن برابر false می‌شود. در صورتی که چنین قصدی ندارید باید از عملگرهای وجودی CoffeeScript استفاده کنید که تنها در حالیکه hash برابر null و یا undefined باشد، فعال می‌شوند.
hash ?= {}
نتیجه‌ی کامپایل آن می‌شود:
if (typeof hash !== "undefined" && hash !== null) {
  hash;
} else {
  hash = {};
};
مطالب
فراخوانی سرویس‌های OData توسط کلاینت‌های #C
فرض کنید در سرویس‌های خود، در حال استفاده از OData هستید. حال کافیست که metadata$ مربوط به سرویستان را برای استفاده‌ی کلاینت‌های دیگر، در اختیار آن‌ها قرار دهید.
وقتی از Odata استفاده میکنید، به صورت خودکار metadataی از سرویس‌ها و مدل‌های شما ساخته میشود و میتوان از آن به عنوان یک documentation کامل نام برد و حتی افرادی که استاندارد‌های Odata را نمیشناسند، به راحتی میتوانند آن را مطالعه و در صورت اجازه‌ی شما، از امکانات آن سرویس‌ها، در نرم افزار خودشان استفاده کنند.
بطور مثال میتوانید متادیتای برنامه‌ی خود را با استفاده از آدرس فرضی http://localhost:port/odata/$metadata مشاهده نمایید؛ که چیزی شبیه به محتوای زیر خواهد بود:
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OwinAspNetCore.Models">
<EntityType Name="Product">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Name" Type="Edm.String"/>
<Property Name="Price" Type="Edm.Decimal" Nullable="false"/>
</EntityType>
</Schema>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Default">
<Function Name="TestFunction" IsBound="true">
<Parameter Name="bindingParameter" Type="Collection(OwinAspNetCore.Models.Product)"/>
<Parameter Name="Val" Type="Edm.Int32" Nullable="false"/>
<Parameter Name="Name" Type="Edm.String"/>
<ReturnType Type="Edm.Int32" Nullable="false"/>
</Function>
<EntityContainer Name="Container">
<EntitySet Name="Products" EntityType="OwinAspNetCore.Models.Product"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
در اینجا میتوان EntityTypeها ، EntitySetها و همه‌ی Action‌ها و Function‌های خود را مشاهده نمایید.
به غیر از این، وجود metadata باعث شده به راحتی کلاینت‌های #JavaScript ،Java ،Objective-C ،C و ... بتوانند به راحتی ارتباط کاملی با سرویس‌های شما برقرار نمایند.
برای مثال به صورت معمول یک کلاینت #Cی برای ارتباط برقرار کردن با یک سرویس خارجی باید اینگونه عمل کند (یک درخواست از نوع POST):
string postUrl = "http://localhost:port/....";
HttpClient client = new HttpClient();
var response = client.PostAsync(postUrl, new StringContent(JsonConvert.SerializeObject(new { Rating = 5 }), Encoding.UTF8, "application/json")).Result;
مشکلات این روش کاملا روشن و گویاست: پیچیدگی خیلی زیاد، دیباگ خیلی سخت و refactoring پیچیده و ...
اگر مطالب قبلی را دنبال کرده باشید، به پیاده سازی سرویس‌های Odata پرداختیم. در این لینک یک repository کامل برای کار با odata در asp.net core آماده شده‌است و در این مقاله از آن استفاده نموده‌ام.
بعد از clone کردن آن، پروژه را run نمایید. به چیز بیشتری از آن نیازی نداریم.
حال کافیست یک پروژه‌ی Console Application را ساخته و بعد باید از طریق منوی Tools گزینه‌ی Extensions and Updates را انتخاب و odata v4 client code generator را جستجو نماییم:

آن را نصب نموده و بعد از تکمیل شدن، visual studio را restart کنید.

پروژه‌ی console خود را باز کرده و از طریق Add -> new item، آیتم OData client را جستجو کرده و با نام ProductClient.tt آن را تولید نمایید (نام آن اختیاری است):

فایل ProductClient.tt را که یک T4 code generator میباشد، باز کرده و مقدار ثابت MetadataDocumentUri را به آدرس سرویس odata خود تغییر دهید:

public const string MetadataDocumentUri = "http://localhost:port/odata/";

روی این آیتم کلیک راست و گزینه‌ی Run Custom tool را انتخاب نمایید. این تمام کاری است که نیاز به انجام دادن دارید.

حال فایل Program.cs را باز کرده و آن‌را اینگونه تغییر دهید:

using ConsoleApplication1.OwinAspNetCore.Models;
using System;
using System.Linq;
namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:24977/odata");

            //var context = new Default.Container(uri);
            var context = new TestNameSpace.TestNameSpace(uri);

            //get
            var products = context.Products.Where(pr => pr.Name.Contains("a"))
                .Take(1).Select(pr => new { Firstname = pr.Name, PriceValue = pr.Price }).ToList();

            //add
            context.AddToProducts(new Product() { Name = "Name1", Price = 123 });

            //update
            Product p = context.Products.First();
            p.Name = "changed";
            context.UpdateObject(p);

            //delete
            context.DeleteObject(context.Products.Last());

            //commit
            context.SaveChanges();
        }
    }
}
اینبار همه چیز strongly typed و با همان intellisense معروف خواهد بود. فقط دقت کنید که اگر از Repository معرفی شده، برای سمت سرور خود استفاده میکنید، به دلیل اینکه از Namespace استفاده کرده‌ام، context شما، به نام namespace شما خواهد بود. در غیر اینصورت به صورت default و بدون namespace، باید از Default.Container استفاده شود.

مشاهده میفرمایید که همه‌ی عملیات‌های لازم برای CRUD، به شرط اینکه در سمت سرور طراحی شده باشند، به راحتی از سمت کلاینت قابل فراخوانی خواهند بود.

از این ویژگی فوق العاده میتوان حتی در کلاینت‌ها جاوااسکریپتی نیز استفاده کرد. فرض کنید نرم افزار تحت وبی را با استفاده از jquery یا angularjs طراحی کرده‌اید. قاعدتا فراخوانی درخواست‌های شما به سمت سرور، چیزی شبیه به این خواهد بود:

//angularjs
$http.get("/products/get", {Name: "Test", Company: "Test"})
    .then(function(response) {
        console.log(response.data);
    });

//jquery
$.get("/products/get", {Name: "Test", Company: "Test"}, function(data, status){
        console.log("Data: " + data);
    });

با استفاده از odata و typescript و یک library مربوط به odata client در سمت کلاینت، نرم افزار شما بجای موارد، بالا چیزی شبیه به مثال زیر خواهد بود (با همراه داشتن strongly typed و intellisense کامل)

let product1 = await context.products.filter(c => c.Name.contains("Ali")).toArray();
let product2 = await context.products.getSomeFunction(1, 'Test');
context.product.add({Name: 'Test'} as Product);
await context.saveChanges()


در مقاله‌های آتی به ویژگی‌های بیشتری از Odata خواهیم پرداخت.

بازخوردهای دوره
کار با RavenDB از طریق REST API آن

با تشکر فراوان از شما

برای کار با حجم زیاده داده آیا حالت نصب embedded را پیشنهاد میکنید؟

بین RavenDB و MongoDB در پلت فورم Asp.net MVC 4 کدامیک را پیشنهاد میکنید؟

نظرات مطالب
اختصاصی کردن Razor برای #C در MVC با استفاده از Extension Method
در حالت عادی RazorViewEngine هنگام Load کردن یک View به دنبال View‌های مربوط به C# و VB و حتی aspx میگردد:

Razor View Engine without filter

ولی اگر اصلاحات فوق برای RazorViewEngine انجام گیرد، Engine فقط به دنبال View‌های مربوط به C# میگردد:

Razor View Engine with filter

در واقع این کار به افزایش سرعت Razor کمک میکند و در Scale بالا میتونه موثر باشه
سوال دیگه هست در خدمتم
مطالب
پالایش درخواست ها در IIS

شاید شما هم قصد داشته باشید تا از برخی درخواست‌ها به وب سایت یا اپلیکیشن خود ممانعت عمل بیاورید. نظیر درخواست‌های SQL Injection یا برخی Query String‌های خاص یا برخی درخواست‌های مزاحم.

یکی از مزاحمت هایی که گریبانگیر وب سایت هاست، Bot‌های متفاوتی است که برای کپی اطلاعات، درج کامنت به صورت خودکار و مواردی از این دست، به آنها مراجعه میکنند. شاید در نگاه اول بد نباشد که این Bot‌ها به سراغ وب سایت ما بیایند و باعث افزایش تعداد ویزیت سایتمان شوند؛ ولی ضررهای ناشی از کپی و سرقت مطالب سایت، آنهم با سرعت بالا، بیشتر از منافع ناشی از بالا رفتن رنک سایت است. به طور مثال همین سایت NET Tips. دارای تعداد زیادی مقالات مفید است که افراد متعددی در نگارش و تهیه آن‌ها زحمت کشیده اند، یا وب سایتی برای جلب اعتماد مشتریان جهت درج اطلاعاتشان و یا آگهی هایشان زحمت زیادی کشیده است، Bot‌های آماده‌ی زیادی وجود دارد که با چند دقیقه صرف وقت جهت تنظیم شدن آماده میشوند تا مطالب را طبق ساختار تعیین شده، مورد به مورد کپی کنند.

برای خلاصی از این موارد  روش‌های متعددی وجود دارد که از جمله آنها می‌توان به تنظیمات فایل htaccess در وب سرورهایی نظیر Apache و یا web.config در IIS اشاره کرد. در این مقاله این امکان را با IIS مرور میکنیم و برای فعال سازی آن کافی است در:

  • IIS 7.5 و بالاتر، همراه با انتخاب Request Filtering در مراحل نصب IIS

  • IIS 6.0 با نصب URLScan 3.0 

 در بخش <system.webServer>  و سپس <security>، تگ requestFiltering را استفاده کنیم، در این تگ دستورالعمل‌های ویژه‌ی پالایشگر درخواست‌ها را مینویسیم (filteringRules) هر دستورالعمل پالایش دارای خصیصه‌های (Attributes) زیر است:

 denyUnescapedPercent   
مقدار Boolean و انتخابی
اگر برابر با true تنظیم گردد، درخواست هایی که دارای کاراکتر "درصد" (%) هستند و به وسیله escape character ها پوشش داده نشده باشند، رد می‌شوند. (جهت جلوگیری از حملات XSS و...)
مقدار پیش فرض true است.
 
 name
عنوان دستورالعمل.
مقدار پیش فرض نداشته و درج کردن آن اجباری است.

scanAllRaw
مقدار Boolean و انتخابی
اگر برابر با true تنظیم گردد، پالایشگر درخواست‌ها موظف است تا با بررسی متن header های درخواست، در صورت یافتن یکی از واژه هایی که در خصیصه denyStrings ذکر کرده اید، درخواست را رد کند.
مقدار پیش فرض false است.
 
 scanQueryString   
مقدار Boolean و انتخابی
اگر برابر با true تنظیم گردد، پالایشگر درخواست‌ها موظف است تا Query string را بررسی کند تا در صورتی که یکی از واژه‌های درج شده در خصیصه denyStrings را بیابد، درخواست را رد کند.
اگر خصیصه‌ی unescapeQueryString از تگ < requestFiltering > برابر با true باشد، query string دوبار بررسی می‌شود: یکبار متن query string برای یافتن عبارات ممنوعه و بار دیگر برای یافتن کاراکترهای بدون پوشش scaped .
مقدار پیشفرض false است.
 
 scanUrl   
مقدار Boolean و انتخابی
اگر برابر با true تنظیم گردد، پالایشگر درخواست‌ها URL را برای یافتن واژه‌های ممنوعه‌ی ذکر شده در خصیصه denyStrings بررسی می‌نماید.
مقدار پیش فرض false است.
 

چند مثال:
مثال 1: در این مثال عنوان User-Agent هایی را که در موارد متعدد برای وب سایت هایی که روی آنها کار میکردم مزاحمت ایجاد میکردند را پالایش میکنیم. (لیست این Bot‌ها آپدیت میشود)
<requestFiltering>
  <filteringRules>
    <filteringRule name="BlockSearchEngines" scanUrl="false" scanQueryString="false">
      <scanHeaders>
        <clear />
        <add requestHeader="User-Agent" />
      </scanHeaders>
      <appliesTo>
        <clear />
      </appliesTo>
      <denyStrings>
        <clear />
        <add string="Python UrlLib" />
        <add string="WGet" />
        <add string="Apache HttpClient" />
        <add string="Unknown Bot" />
        <add string="Yandex Spider" />
        <add string="libwww-perl" />
        <add string="Nutch" />
        <add string="DotBot" />
        <add string="CCBot" />
        <add string="Majestic 12 Bot" />
        <add string="Java" />
        <add string="Link Checker" />
        <add string="Baiduspider" />
        <add string="Exabot" />
        <add string="PHP" />
      </denyStrings>
    </filteringRule>
  </filteringRules>
</requestFiltering>

مثال 2: ممانعت از SQL Injection

<requestFiltering>
   <filteringRules>
      <filteringRule name="SQLInjection" scanUrl="false" scanQueryString="true">
         <appliesTo>
            <clear />
            <add fileExtension=".asp" />
            <add fileExtension=".aspx" />
            <add fileExtension=".php" />
         </appliesTo>
         <denyStrings>
            <clear />
            <add string="--" />
            <add string=";" />
            <add string="/*" />
            <add string="@" />
            <add string="char" />
            <add string="alter" />
            <add string="begin" />
            <add string="cast" />
            <add string="create" />
            <add string="cursor" />
            <add string="declare" />
            <add string="delete" />
            <add string="drop" />
            <add string="end" />
            <add string="exec" />
            <add string="fetch" />
            <add string="insert" />
            <add string="kill" />
            <add string="open" />
            <add string="select" />
            <add string="sys" />
            <add string="table" />
            <add string="update" />
         </denyStrings>
         <scanHeaders>
            <clear />
         </scanHeaders>
      </filteringRule>
   </filteringRules>
</requestFiltering>

مثال 3: ممانعت از درخواست انواع خاصی از فایل ها

<requestFiltering>
   <filteringRules>
      <filteringRule name="Block Image Leeching" scanUrl="false" scanQueryString="false" scanAllRaw="false">
         <scanHeaders>
            <add requestHeader="User-agent" />
         </scanHeaders>
         <appliesTo>
            <add fileExtension=".zip" />
            <add fileExtension=".rar" />
            <add fileExtension=".exe" />
         </appliesTo>
         <denyStrings>
            <add string="leech-bot" />
         </denyStrings>
      </filteringRule>
   </filteringRules>
</requestFiltering>

اطلاعات بیشتر در وب سایت رسمی IIS

مطالب
Debugger visualizers

از VS.Net 2005 به بعد، امکانات اشکال زدایی کدها به شدت بهبود یافته و یکی از امکانات جالبی که به آن اضافه شده است، Debugger visualizers می‌باشد، یعنی امکان مشاهده‌ی محتوای اشیاء در حین دیباگ. همچنین با استفاده از SDK ویژوال استودیو، برنامه نویس‌ها می‌توانند Debugger visualizers سفارشی خودشان را نیز تهیه کنند. در ادامه به تعدادی از این موارد اشاره خواهد شد:
  • Xml Visualizer v.2 - site
  • Data Debugger Visualizer - site
  • WCF Visualizers Tool - site
  • IL Visualizer - site
  • DB Connection Visualizer - site
  • LINQ to SQL Debug Visualizer - site
  • Graphics Debugger Visualizer - site
  • Bitmap Debugger Visualizer - site
  • PowerShell Debug Visualizer - site
  • WebVisualizers - site
  • Sharepoint debug visualizer - site
  • WPF Tree Debugger Visualizer - site
  • GUID Debugger Visualizer - site
  • WindowsIdentity Debugger Visualizer - site
  • ControlTree visualizer - site
  • Regular Expression Visualizers - site
  • Improving Visual C++ Debugging - site

اشتراک‌ها
Visual Studio 2017 15.6 منتشر شد
Visual Studio 2017 15.6 منتشر شد
نظرات مطالب
قسمت دوم -- نگاهی دقیق تر به اولین پروژه VC++ (درک مفهوم فایلهای سرآیند و فضای نام ، ویژگیهای زبان ++C و برخی قوانین برنامه نویسی در ++C)
عنوان مطلب صحیح نیست لطفا تغییر دهید،
در فضای برنامه نویسی مراد از VC.NET زبان برنامه نویسی CPP تحت CLI است یعنی با سینتکس CPP و کامپایلر .NET یعنی همان کامپایلری که C#.NET و VB.NET استفاده می‌کنند. یا به عبارتی Managed CPP. در منوی New Project در Visual Studio گزینه CLR باید انتخاب شود.

آموزش هایی که شما ارائه کرده اید مربوط به Native CPP است. برنامه نویسی MFC یا VCL یا Win32 یا.. متفاوت با VC++.NET است.در منوی New Project در Visual Studio گزینه‌های غیر از CLR همگی native  هستند.

بهتر است مشابه msdn از واژه ++Visual C  استفاده کنید:
++Visual C
++NET Programming in Visual C.

با تشکر
نظرات مطالب
اختصاصی کردن Razor برای #C در MVC با استفاده از Extension Method
این مطلب در حقیقت تکمیلی است بر «بهبود سرعت نمایش صفحات در ASP.NET MVC با حذف View Engines اضافی». در حالت RazorViewEngine تنها، هم فایل‌های cs و هم vb پردازش می‌شوند. در مطلب جاری پردازش فایل‌های vb آن هم فیلتر شده‌اند (توسط متد DisableVbhtml) و فقط فایل‌های cs باقی مانده‌اند.