نظرات مطالب
یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017
فایل zip پیوستی انتهای بحث را دریافت کنید. در فایل src\app\app.module.ts آن، تعریف ذیل برای معرفی HttpModule وجود دارد و بدون آن، استثنای No provider for Http را دریافت خواهید کرد:
import { HttpModule } from '@angular/http';

@NgModule({
  imports: [
    HttpModule
  ]
مطالب
فایل آپلود در AngularJs
در این بخش قصد داریم تا به چگونگی آپلود فایل در AngularJs بپردازیم. پلاگین‌های فراوانی جهت آپلود فایل وجود دارند، از جمله ng-file-Upload ، angular-file-upload و jquery-file-upload. البته نمونه‌ی ذکر شده‌ی آخر، یکی از پلاگین‌های معروف JQuery است که با AngularJs هم سازگار شده است.
ما قصد داریم تا در این مجموعه از ng-file-upload که توسط Danial Farid  توسعه داده شده است، استفاده نماییم. این پلاگین شامل یک دایرکتیو کم حجم برای مدیریت آپلود فایل سمت کلاینت است و با تمامی تکنولوژی‌های سمت سرور سازگار می‌باشد. صفحه‌ی دمو پلاگین، شامل برخی از امکانات ذکر شده می‌باشد که قرار است به توسعه و بحث پیرامون آن بپردازیم. این مجموعه دارای اسناد معتبری است که می‌توانید از آن برای توسعه‌ی هر گونه آپلود فایل استفاده نمایید. نسخه‌ی فعلی، نسخه‌ی منتشر شده‌ی 3.0 است. نسخه‌های قبلی این پلاگین نیز در سایت GitHub موجود است.

ویژگی ها

در بخش زیر ویژگی‌های این افزونه که در اسناد آن نیز موجود است، شرح داده شده است:
  • امکان ایجاد progress bar و همچنین قابلیت لغو آپلود.
  • Drag & Drop
  • امکان paste کردن از Clipboard و قابلیت drag & drop از browser
  • امکان resize کردن تصویر قبل از آپلود شدن
  • امکان تغییر دادن orientation تصویر پیش از ارسال
  • قابلیت resume و pause/play در آپلود
  • امکان فیلتر کردن type، size و طول و عرض تصاویر
  • قابلیت تبدیل به Flash shim در صورت عدم پشتیبانی html5 توسط مرورگر

نصب و پیاده سازی

برای استفاده‌ی از پلاگین file upload لازم است که دو مجموعه‌ی زیر را توسط Nuget یا Bower دریافت نمایید. پلاگین اول مربوط به مرورگرهایی است که از html5 پشتیبانی نمی‌کنند.
bower install ng-file-upload-shim --save
bower install ng-file-upload --save
پس از اینکه دو کامپوننت فوق را نصب نمودید، دو فایل اسکریپت دریافت شده را به فایل main html اضافه نمایید. پس آن شروع به نوشتن یک مثال ساده می‌کنیم.
این مثال در JSFIDDLE قرار داده شده است، به این صورت که در این مثال یک فایل آپلود ساده در قالب یک فرم به سرور ارسال می‌گردد. امکانات خیلی ساده نظیر نمایش فایل، پیش از آپلود نیز در این قسمت قرار داده شده است.
به عنوان اولین گام به کد زیر توجه کنید:
<input type="file" ngf-select ng-model="picFile" name="file" accept="image/*" ngf-max-size="2MB" required>
تکه کد فوق مربوط به تگ آپلود فایل است که به توضیح آن خواهیم پرداخت. ngf-select Attribute دایرکتیوی برای تبدیل فایل آپلود، به ng-file-upload است. شما به طور کلی به دو صورت قادر هستید که این کار را انجام دهید. مورد اول ngf-select بود و مورد بعدی ngf-drop است. ngf-drop به گونه‌ای دیگر نوشته می‌شود و کد زیر یک مورد استفاده‌ی از ngf-drop می‌باشد.
<div ngf-drop ng-model="picFile" ngf-pattern="image/*">
     ...
</div>
همانطور که ملاحظه می‌کنید در این نوع فراخوانی، یک تگ div به یک file select مبدل شده که در مورد آن صحبت خواهیم نمود. همانطور که مشاهده می‌کنید، شما قادرید تا با استفاده از Attribute ایی با نام accept، فایل‌های ارسالی را از لحاظ محتوایی فیلتر کنید. در کد فوق image/* این مفهوم را می‌رساند که شما قادرید فایل‌های تصویری و با هر فرمتی را به سرور ارسال نمایید. اما اگر آن را به صورت image/jpg بنویسیم این عملیات تنها به تصاویر با فرمت jpeg منتهی می‌شود. مورد بعدی محدودیت حجمی تصویر است. شما با ngf-max-size و مقداری که درون آن قرار می‌دهید، قادرید تا محدودیت حجمی را بر روی فایل‌های ارسالی به سرور اعمال نمایید. اگر با نوشتار form validationها در Angular آشنا باشید، به سادگی قادرید تا خطاهایی را که کاربر ممکن است در حین آپلود انجام دهد، به او گوشزد کنید. به کد زیر توجه کنید:
<i ng-show="myForm.file.$error.required">*required</i><br>
<i ng-show="myForm.file.$error.maxSize">
File too large: max is 2M
</i>
همانطور که مشاهده می‌کنید syntax نمایش خطاها دقیقا مانند نمایش خطاها در validation فرم‌های انگیولاری است.
و اما اینکه چه کارهایی نیاز است تا در سمت Controller انجام دهیم. اول اینکه لازم است شما dependency ngFileUpload زیر را به app.module اضافه نمایید. حال اینکه پس از inject کردن این وابستگی، تنها کافیست که وابستگی Upload را به کنترلر تزریق نمایید. این وابستگی وظیفه‌ی ارسال فایل به سرور را بر عهده دارد. به مثال زیر توجه نمایید:
app.controller('MyCtrl', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
    // the method uploadPic called from Angular View
$scope.uploadPic = function(file) {
    file.upload = Upload.upload({
      url: 'https://angular-file-upload-cors-srv.appspot.com/upload',
      data: {file: file, otherData: $scope.otherData},
    });

    file.upload.then(function (response) {
// waiting for response
        $timeout(function () {
file.result = response.data;
        });
    }, function (response) {
//error
        if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
    }, function (evt) {
//progress
        file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
console.log(file.progress);
    });
    }
}]);
تمام عملیات در قالب یک فراخواننده‌ی ng-click از سوی view آغاز شده‌است. با این رخداد، متد uploadPic که همراه آن فایل attach شده نیز به عنوان پارامتر ارسال می‌گردد، فرخوانی می‌شود و کلیه‌ی کارها طی عملیات post، توسط وابستگی Upload برای سرور ارسال می‌گردد. همانند http$ درون بلاک then سه متد Success ، Error و progress پیاده‌سازی شده است. البته اگر به فرایند مقداردهی Url و data توجه کنید می‌بینید که فایل‌ها نیز درون data قرار گرفته‌اند. شما برای ارسال فایل‌ها می‌توانید از وابستگی upload$ نیز استفاده کنید که مثالی هم در این زمینه در mono-software.com پیاده‌سازی شده است که از ng-file-upload و در سمت سرور، از ASP.NET Web API استفاده می‌کند. در این مثال چندین فایل به صورت غیر همزمان برای سرور ارسال می‌گردند.
توحه داشته باشید که شما برای uploadهای ساده، قادر هستید تا دایرکتیو خاص خود را نوشته و از آن استفاده نمایید. در msdn نمونه‌ای از این کار، یعنی نوشتن دایرکتیو فایل آپلود، به طور کامل پیاده‌سازی شده است. اما مزیت ng-file-upload این است که این پلاگین، با بسیاری از پلاگین‌های 3rd party دیگر مانند ng-image-crop به خوبی همگام شده‌است. مثالی از آن را می‌توانید در اینجا مشاهده نمایید.
در این مقاله، هدف کلی، چگونگی فایل آپلود در AngularJs و پس از آن معرفی و بررسی ویژگی‌ها و همچنین تشریح عملکرد ng-file-upload بود. این افزونه قابلیت‌های فراوان دیگری نیز دارد که بنابر نیاز می‌توانید در کد‌های خود از آن‌ها استفاده نمایید.
اشتراک‌ها
بررسی زبان Go برای توسعه دهندگان #C

A Tour of Go (golang) for the C# Developer

Learning other programming languages enhances our work in our primary language. From the perspective of a C# developer, the Go language (golang) has many interesting ideas. Go is opinionated on some things (such as where curly braces go and what items are capitalized). Declaring an unused variable causes a compile failure; the use of "blank identifiers" (or "discards" in C#) are common. Concurrency is baked right in to the language through goroutines and channels. Programming by exception is discouraged; it's actually called a "panic" in Go. Instead, errors are treated as states to be handled like any other data state. We'll explore these features (and others) by building an application that uses concurrent operations to get data from a service. These ideas make us think about the way we program and how we can improve our day-to-day work (in C# or elsewhere).

0:00 Welcome to Go
2:40 Step 1: Basics
12:20 Step 2: Calling a web service
23:35 Step 3: Parsing JSON
36:26 Step 4: "for" loops
41:00 Step 5: Interfaces and methods
50:05 Step 6: Time and Args
55:10 Step 7: Concurrency
1:07:10 Step 8: Errors
1:14:40 Step 9: Concurrency and errors
1:24:35 Where to go next 

بررسی زبان Go برای توسعه دهندگان #C
نظرات مطالب
ویژگی Batching در EF Core
کدهای معادل مطلب فوق در EF 6.x را از اینجا دریافت کنید: EF6TestBatching.zip
این کدها برای حالت انجام 2 به روز رسانی و 6 ثبت، کدهای SQL زیر را تولید می‌کنند:
UPDATE [dbo].[Blogs]
SET [Url] = @0
WHERE ([BlogId] = @1)
-- @0: 'http://sample.com/blogs/dogs' (Type = String, Size = -1)
-- @1: '1' (Type = Int32)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 19 ms with result: 1

UPDATE [dbo].[Blogs]
SET [Url] = @0
WHERE ([BlogId] = @1)
-- @0: 'http://sample.com/blogs/cats' (Type = String, Size = -1)
-- @1: '2' (Type = Int32)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 47 ms with result: 1

INSERT [dbo].[Blogs]([Name], [Url])
VALUES (@0, @1)
SELECT [BlogId]
FROM [dbo].[Blogs]
WHERE @@ROWCOUNT > 0 AND [BlogId] = scope_identity()
-- @0: 'The Horse Blog' (Type = String, Size = -1)
-- @1: 'http://sample.com/blogs/horses' (Type = String, Size = -1)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 31 ms with result: SqlDataReader

INSERT [dbo].[Blogs]([Name], [Url])
VALUES (@0, @1)
SELECT [BlogId]
FROM [dbo].[Blogs]
WHERE @@ROWCOUNT > 0 AND [BlogId] = scope_identity()
-- @0: 'The Snake Blog' (Type = String, Size = -1)
-- @1: 'http://sample.com/blogs/snakes' (Type = String, Size = -1)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 73 ms with result: SqlDataReader

INSERT [dbo].[Blogs]([Name], [Url])
VALUES (@0, @1)
SELECT [BlogId]
FROM [dbo].[Blogs]
WHERE @@ROWCOUNT > 0 AND [BlogId] = scope_identity()
-- @0: 'The Fish Blog' (Type = String, Size = -1)
-- @1: 'http://sample.com/blogs/fish' (Type = String, Size = -1)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 49 ms with result: SqlDataReader

INSERT [dbo].[Blogs]([Name], [Url])
VALUES (@0, @1)
SELECT [BlogId]
FROM [dbo].[Blogs]
WHERE @@ROWCOUNT > 0 AND [BlogId] = scope_identity()
-- @0: 'The Koala Blog' (Type = String, Size = -1)
-- @1: 'http://sample.com/blogs/koalas' (Type = String, Size = -1)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 49 ms with result: SqlDataReader

INSERT [dbo].[Blogs]([Name], [Url])
VALUES (@0, @1)
SELECT [BlogId]
FROM [dbo].[Blogs]
WHERE @@ROWCOUNT > 0 AND [BlogId] = scope_identity()
-- @0: 'The Parrot Blog' (Type = String, Size = -1)
-- @1: 'http://sample.com/blogs/parrots' (Type = String, Size = -1)
-- Executing at 16/06/1396 02:31:41 ب.ظ +04:30
-- Completed in 26 ms with result: SqlDataReader

INSERT [dbo].[Blogs]([Name], [Url])
VALUES (@0, @1)
SELECT [BlogId]
FROM [dbo].[Blogs]
WHERE @@ROWCOUNT > 0 AND [BlogId] = scope_identity()
-- @0: 'The Kangaroo Blog' (Type = String, Size = -1)
-- @1: 'http://sample.com/blogs/kangaroos' (Type = String, Size = -1)
-- Executing at 16/06/1396 02:31:42 ب.ظ +04:30
-- Completed in 38 ms with result: SqlDataReader
یعنی در کل 8 بار رفت و برگشت به بانک اطلاعاتی صورت گرفته‌است (هر Executing در اینجا یعنی یکبار رفت و برگشت)؛ در مقابل تنها یکبار رفت و برگشت به بانک اطلاعاتی در حالت استفاده‌ی از EF Core (با تنظیمات پیش فرض آن).
جمع کل مدت زمان عملیات در اینجا 332 میلی ثانیه است در مقایسه با 44 میلی ثانیه EF Core. یعنی EF 6.x در حالت insert/update/delete چیزی حدود 86 درصد از نمونه‌ی EF Core کندتر است و این مورد اهمیت batching و کاهش تعداد رفت و برگشت‌های به بانک اطلاعاتی است که به صورت پیش فرض در EF Core فعال است.
نظرات مطالب
یکپارچه کردن ELMAH با WCF RIA Services
الف - این اسم هر چیزی می‌تونه باشه که در قسمت path ‌های ذکر شده فوق قابل تغییر است (بنابراین از اسم‌های پیش فرض استفاده نکنید).
ب - بهترین مرجع برای ELMAH ، فایل web.config پوشه samples آن است. در این مورد تنظیمات لازم وجود دارد (در مورد بستن دسترسی ریموت یا استفاده از authorization).
خلاصه این دو مورد رو یکی از اعضای اصلی تیم ASP.NET در عمل نشان داده:
http://haacked.com/archive/2007/07/24/securely-implement-elmah-for-plug-and-play-error-logging.aspx
+
http://code.google.com/p/elmah/wiki/SecuringErrorLogPages
نظرات اشتراک‌ها
Raspberry Pi Zero یک کامپیوتر 5 دلاری
این رزبری پی عالیه. نسخه دو 30 دلاری را توی ایران با قیمت 150 تومن میشه گیر آورد. این که دیگه 5 دلاره

اینترنت اشیاء در حال محقق شدنه کم کم ..