مطالب
کش کردن اطلاعات غیر پویا در ASP.Net - قسمت اول

در مورد افزونه YSlow افزونه Firebug فایرفاکس پیشتر صحبت شد. این افزونه پس از آنالیز یک سایت، پیشنهاداتی را نیز جهت بهبود سرعت، ارائه می‌دهد.





همانطور که در شکل بالا مشخص است، عناصری مانند css و js ، قسمت expires اشان (تاریخ منقضی شدن کش آن‌ها در سمت کلاینت) خالی است و پیشنهاد داده که به هر کدام از این عناصر، هدر مخصوص مشخص سازی مدت زمان کش شدن در سمت کلاینت اضافه شود.
ASP.Net در مورد کش کردن اطلاعات صفحات پویا به اندازه‌ی کافی امکانات در اختیار برنامه نویس قرار می‌دهد اما در مورد اضافه کردن این هدر جهت یک فایل css غیر پویا شاید نتوان مطلب خاصی را یافت.
در IIS7 امکانات ویژه‌ای برای این منظور در نظر گرفته شده که نحوه استفاده از آن در ASP.Net به صورت زیر است:
فایل وب کانفیگ سایت را باز کرده و به قسمت system.webServer چند سطر زیر را اضافه کنید:

<staticContent>
<clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
</staticContent>

این مورد فقط مختص به IIS7 است و بر روی نگارش‌های پایین‌تر کار نمی‌کند.
با این کار، تاریخ منقضی شدن هر آنچه که توسط موتور ASP.net سرو نمی‌شود به سال 2020 تنظیم خواهد شد. (کلیه محتوای غیرپویای سایت، اعم از تصاویر، فایلهای css ، js و غیره)
پس از این تنظیم مجددا YSlow را اجرا کرده و Performance Grade ایی را که نمایش می‌دهد بررسی نمائید.

بدیهی است اگر یکی از فایل‌های css یا js شما تغییر کند، کلاینت، اطلاعات جدیدی را تا سال 2020 دریافت نمی‌کند. برای حل این مشکل یک کوئری استرینگ ساده به انتهای لینک مربوط به css‌ یا js‌ خود اضافه کنید تا URL جدید با URL قبلی آن یکسان نباشد (این کوئری استرینگ تاثیری روی محتوای ایستای ما ندارد). به این صورت این آدرس جدید، مجددا دریافت شده و تا سال 2020 کش خواهد شد.

نکته:
اعمال تنظیم فوق، در IIS7 ویندوز سرور 2008 مجاز است؛ اما در IIS7 ویندوز ویستا قفل شده است و قابل override نیست. برای تغییر آن، فایل زیر را پیدا کنید:
open %systemroot%\System32\inetsrv\config\applicationHost.config
و در آن سطر
<section name="staticContent" overrideModeDefault="Deny" />
را به صورت زیر تغییر دهید تا مجاز به اعمال تغییرات شوید:
<section name="staticContent" overrideModeDefault="Allow" />
در قسمت بعد در مورد نگارش‌های پایین‌تر IIS توضیح داده خواهد شد.


مآخذ:
YSlow: Add expires header to images in IIS 7
IIS7: How to set cache control for static content?

نظرات مطالب
زیر نویس فارسی ویدیوهای ساخت برنامه‌های مترو توسط سی شارپ و XAML - قسمت اول
- کار خیلی ارزشمندیه واقعا. و یه سبک نویی هست در تولید محتوا به زبان فارسی.
- توی support سایت گفتن که به زودی زیرنویس برا همه‌ی Course ها خواهیم گذاشت.
- اگر امکان براتون داشته باشه، یه پستی بزنین که نحوه‌ی تولید اسکریپت رو توش توضیح بدین. چون مشکل اصلی اینجاست.
- از اونجایی که فکر میکنم، این کار احتمالا دستی انجام میگیره(یعنی به راحتی نیست)
  یه پیشنهاد دارم: به دلیل تایم‌های کوتاه هر section و بعد از اون هر part از section ها که خیلی کوتاهند. میشه تا اقدام رسمی خود پلورال‌سایت به تولید زیرنویس، فقط حرفهایی که در کلیپ توسط مدرس زده شده نوشته شود(بدون توجه به زمانبدی).
که این میتونه دوجور باشه:
- یکی از الف تا ی.
 - یکی دیگه، صرفا اشاره و رساندن موضوع به صورت تیتر وار.
خب از مزیت‌های این کار:
 - کاهش شدید زمانبری تولید محتواست.
 - توان تولید محتوا(یا اصلاح محتوا) توسط افراد بیشتر.
 - با توجه به ادای شفاف کلمات مدرسان، و با وجود همچین چیزی احتمالا اکثر مطالب قابل فهم‌تر خواهد بود.
 - و شاید جالب‌تر از اینها، گزیده‌‌ نوشته‌هایی خواهند شد، که برای مرور کردن دوره‌ها در آینده بسیار مفید و کارا خواهد بود.
نظرات مطالب
PersianDateTime جایگزینی برای System.DateTime
این تمام کد برنامه است :
using System;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //  این قسمت برای ورود اطلاعات به بانک است و با کمک کتابخانه پرژن دات نت  تاریخ شمسی را به میلادی تبدیل و ذخیره میکنم
            using(var db = new h7Entities())
            {
                var t = new test
                {
                    ResponseDate = PersianDateTime.Parse(textBox1.Text).ToDateTime()
                };
                db.test.Add(t);
                db.SaveChanges();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // این قسمت هم فقط اطلاعات واکشی شده را در گرید نمایش میدهد . بدون هیچ شرطی ، یک سلکت ساده . . فقط از پرژن دانت نت برای تبدیل میلادی به شمسی کمک میگیرم
            using (var db = new h7Entities())
            {
                dataGridView1.DataSource =(from t in db.test
                                              select  new
                                              { 
                                                  Id= t.Id,
                                                  time = new PersianDateTime(DateTime.Parse(t.ResponseDate.ToString())).ToString(PersianDateTimeFormat.DateShortTime)
                                              }).ToList();                
            }

        }
    }
}

کتابخانه PersianDateTime  را از نیوگت دریافت کردم .
ولی چیزی در گرید نمایش نمیدهد .

مدل برنامه هم :

 public partial class test
    {
        public int Id { get; set; }
        public Nullable<System.DateTime> ResponseDate { get; set; }
    }


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


حالا چطور از فیلدی که تاریخ را نمایش میدهد فقط آن را تبدیل به شمسی و نمایش دهد ؟ شبیه این  1365/02/02    ؟
تشکر
مطالب
ایجاد شناسه ی منحصر به فرد برای هر سیستم
چند روز پیش یک افزونه در nuget نظرم رو به خودش جلب کرد . بعد از دانلود و نصب اون و مقداری کار کردن باهاش جای خودش رو تو دلم باز کرد ولی متاسفانه این افزونه تا 21 روز رایگان بود. توی نت برای پیدا کردن سریال و یا کرکش زیاد گشتم ولی هیچ چیز یافت نشد . شاید به خاطر اینکه از زمان تولیدش زیاد نمیگذره ... در هر حال گذشتن از خیرش برام سخت بود بنابر این به یاد قدیم تصمیم گرفتم خودم دست به کار بشم و release کنمش ... 
بعد از deobfuscate  کردنش سیستم امنیتیش نکات خیلی جالبی داشت که یکیش ایجاد شناسه‌ی منحصر به فرد برای هر سیستم بود . البته شاید باورش سخت باشه ولی برای بخش امنیتش 23 تا کلاس داشت که هر کدوم کلی تابع و ... داشتن که همه هم به هم مرتبط بود . تا به حال ندیده بودم توی هیچ افزونه ای اینقدر روی امنیتش کار بشه و خب همینم باعث شد 5-4 ساعت وقتمو بگیره ...

کد زیر رو از یکی از کلاس هاش استخراج کردم که توسط اون میتونید یک شناسه منحصر به فرد بر اساس مشخصات پردازنده - برد اصلی و ... تولید کنید . فقط در هنگام استفاده توجه داشته باشید به ارجاع‌های برنامه و اینکه باید System.Management رو به reference‌های برنامه اضافه بکنید حتما ...

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Win32;
using System.Management;

namespace ConsoleApplication1
{

    class Program
    {
        private static string GetSystemCode_int1(byte[] byte_0)
        {
            if (byte_0 != null)
            {
                return Convert.ToBase64String((new MD5CryptoServiceProvider()).ComputeHash(byte_0));
            }
            else
            {
                return string.Empty;
            }
        }

        private static string GetSystemCode_int0(string string_2)
        {
            if (!string.IsNullOrEmpty(string_2))
            {
                return GetSystemCode_int1(Encoding.UTF8.GetBytes(string_2));
            }
            else
            {
                return string.Empty;
            }
        }

        public static string GetSystemCode()
        {
            string key = null;
            if (key == null)
            {
                string empty = string.Empty;
                try
                {
                    ManagementClass managementClass = new ManagementClass("win32_processor");
                    ManagementObjectCollection instances = managementClass.GetInstances();
                    foreach (ManagementBaseObject instance in instances)
                    {
                        try
                        {
                            empty = string.Concat(empty, instance.Properties["processorID"].Value.ToString());
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
                catch
                {
                    try
                    {
                        ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("Select * From Win32_BaseBoard");
                        foreach (ManagementBaseObject managementBaseObject in managementObjectSearcher.Get())
                        {
                            empty = string.Concat(empty, managementBaseObject["SerialNumber"].ToString().Trim());
                        }
                    }
                    catch
                    {
                    }
                }
                try
                {
                    ManagementObject managementObject = new ManagementObject("win32_logicaldisk.deviceid=\"C:\"");
                    managementObject.Get();
                    empty = string.Concat(empty, managementObject["VolumeSerialNumber"].ToString());
                }
                catch
                {
                }
                if (string.IsNullOrWhiteSpace(empty))
                {
                    empty = Environment.MachineName;
                }
                key = GetSystemCode_int0(empty);
            }
            return key;
        }

        static void Main(string[] args)
        {
            Console.WriteLine(GetSystemCode());
            Console.ReadKey();
        }
    }
}
نظرات مطالب
ASP.NET MVC #11
در قسمت آخر مطلبتون یک ModelBinder  سفارشی برای DateTime نوشته شده که روش خوب و مناسبی هست برای جلوگیری از تکرار کد اضافی. اما یک مشکلی که من دارم اینه این روش شما برای گرفتن اطلاعات از کلاینت درست عمل میکنه اما مشکل اینجاست اگر من بخوام این فیلد تاریخ رو به کاربر نشون بدم چه کاری باید انجام بدم؟یعنی من این فیلد رو از دیتابیس خوندم چطور میشه اونو به مقدار شمسی تبدیل کنم و به کاربر نشون بدم ! چون مقدار تاریخ شمسی برای یک DateTime ‌قابل قبول نیست(راهی ک من برای حل مشکل داشتم این بود که یک فیلد String در viewmodel‌قرار میدادم و مقادیر اونو وقتی اطلاعات از سمت کاربر میومد به مقدار میلادی تبدیل می‌کردم و در فیلد مربوطه قرار میدادم و وقتی اطلاعات رو از دیتابیس لود میکردم مقدار فیلد تاریخ رو به شمسی تبدیل می‌کردم و در فیلد  string میذاشتم.)
نظرات مطالب
متدهای کمکی مفید در پروژه های asp.net mvc
خروجی json در یک View یعنی متغیری از نوع جاوا اسکریپت. این متغیر به صورت مستقیم در کدهای یک htmlHelper قابل استفاده نیست (چون از نوع دات نت و سی شارپ یا وی بی است).
در اینجا تبدیل تاریخ مدنظر را باید همان طرف کدهای کنترلر انجام داد. یا این طرف از توابع جاوا اسکریپتی تبدیل تاریخ میلادی به شمسی باید استفاده کرد. دو context مختلف را نمی‌شود در آن واحد با هم ترکیب کرد.
البته می‌شود داخل کدهای جاوا اسکریپتی یک View از کدهای مثلا Razor استفاده کرد اما این کدها در زمان اجرا به صورت جاوا اسکریپتی پردازش و رندر می‌شوند و نه به فرمت مثلا سی شارپ. برای نمونه می‌شود در یک View داخل کدهای JavaScript موجود از Url.Action استفاده کرد. این مورد در زمان اجرا فقط تبدیل به یک رشته JavaScript می‌شود. البته این نکته برای بکارگیری Html.FarsiDateAndTime نیز صدق می‌کند و فراخوانی آن باید داخل کدهای Ajax جاوا اسکریپتی یک View باشد (و نه خارج از آن چون context دیگر JavaScript نخواهد بود). همچنین باید درنظر داشت که Html.FarsiDateAndTime در زمان رندر شدن جاوا اسکریپت موجود در یک View، تبدیل به معادل رشته‌ای آن شده و جایگزین می‌شود. یعنی در قسمت نتیجه یک عملیات Ajax قابل استفاده نخواهد بود.

نظرات مطالب
ASP.NET MVC #11
با سلام
در صورتی که برای ایجاد فرم‌ها از خاصیت Scaffold template استفاده کنیم دستور BeginForm  مقادیر controller و Action  مقداری ندارند . هنگامی که فرم submit  می‌شود از بر چه اساسی Action  کنترلر مربوطه اجرا می‌شود ؟
کنترلر براساس مدل تعریف شده در ابتدای View انتخاب می‌شود ؟
Action  بر اساس نام فایل ؟
2- در تمامی مثالها از برای نمایش View‌ها از Model‌های ساده استفاده شده بود . در صورتی که بخواهم در یک view از Modeli  استفاده کنم که یک Property آن لیستی از یک Model  دیگر باشد به چه صورت است ؟
آیا باید view‌ها را همیشه به Model‌های جدا تفکیک کنیم ؟
3- هنگام سفارشی سازی model Binder در مثال شما مربوط به ورودی تاریخ شمسی و تبدیل آن به تاریخ میلادی کدی که در application_start اضافه شد مشخص می‌کرد در هر model  که  type فقط  از نوع Datetime  باشد اعمال گردد ؟
با توجه به مثال در صورتی که بخواهم فقط بر روی Create اعمال گردد در صورتی که معرفی binder را از Application_start حذف کنم بر روی تمامی Property ‌ها اعمال میگردد . در صورتی هم که حذف نکنم باز هم بر روی تمامی Action ‌ها اعمال می‌شود .

با تشکر
 
مطالب
وی‍‍ژگی های پیشرفته ی AutoMapper - قسمت دوم
در ادامه قسمت قبلی به برسی ویژگی‌های پیشرفته‌ی AutoMapper می‌پردازیم...


Custom type converters
همانطور که از اسمش مشخصه، زمانی کاربرد داره که نوع عضو یا اعضای یک شی در مبداء، با معادلشون در مقصد یکی نیستند. مثلا فرض کنید نوع Bool در مبداء رو می‌خواهیم به نوع String در مقصد نگاشت کنیم؛ همون Yes و No  معروف بجای True یا False .
کلاس‌های زیر رو در نظر بگیرید:
public class Source
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
    public string Value3 { get; set; }
}

public class Destination
{
    public int Value1 { get; set; }
    public DateTime Value2 { get; set; }
    public Type Value3 { get; set; }
}
طبق مستندات AutoMapper  اگه بخواهیم این دو رو نگاشت کنیم Exception  میده چون AutoMapper  نمیدونه چطوری باید مثلا Int  رو به String تبدیل کنه؛ برای همین ما باید به AutoMapper  بگیم چطور این تبدیل نوع رو انجام بده.

نکته: در تستی که من انجام دادم، AutoMapper  تبدیل نوع‌های ابتدایی رو خودش انجام میده؛ مثلا همین تبدیل Int به String  رو!

یکی از روش‌های مهیا کردن تبدیل کننده‌ی نوع، پیاده سازی اینترفیس ITypeConverter<TSource, TDestination> هست. تقریبا مثل کاری که در WPF  و SL با پیاده سازی اینترفیس IValueConverter انجام می‌دادیم.   
من برای تست از همون  تبدیل نوع Bool  به String استفاده میکنم و البته بخاطر ساده بودن دیگه  Model ‌ها رو نمی‌نویسم.
ابتدا تعریف کلاس تبدیل کننده‌ی نوع:
public class BooltoStringTypeConvertor : ITypeConverter<bool, string>
    {
        public string Convert(ResolutionContext context)
        {
            return (bool)context.SourceValue ? "Yes" : "No";
        }
    }
و نحوه استفاده:
Mapper.CreateMap<bool,string>().ConvertUsing<BooltoStringTypeConvertor>();
            Mapper.CreateMap<Product, ProductDto>();
            Mapper.AssertConfigurationIsValid();

var product = new Product { Id = 1,Name ="PC" ,InStock = true };
var productDto = Mapper.Map<Product, ProductDto>(product);
خروجی به شکل زیر میشه.

نکته: TypeConvertor‌ها میدان دیدشون سراسریه و نیازی نیست به ازای هر نگاشتی اونو به AutoMapper  معرفی کنیم Global Scope.

Custom value resolvers

کلاس‌های زیر رو در نظر بگیرید

public class Person
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

public class PersonDTO
{
    public int Id { get; set; }

    public string RawData { get; set; }
}
فرض کنید داخل RawData  تمامی اعضای شی مبداء رو به صورت Comma Delimited ذخیره کنیم. برای این کار می‌تونیم از Value Resolver استفاده کنیم.
یک روش برای این کار ارث بری از کلاس Abstract  ی بنام ValueResolver<TSource, TDestination> هست.
public class CommaDelimetedResolver:ValueResolver<Person,string>
    {
        protected override string ResolveCore(Person source)
        {
            return string.Join(",", source.Id, source.FirstName, source.LastName);
        }
    }
و نحوه استفاده
Mapper.CreateMap<Person, PersonDTO>().ForMember(
                des => des.RawData, op => op.ResolveUsing<CommaDelimetedResolver>());


var person = new Person
{
Id = 1,
FirstName = "Mohammad",
LastName = "Saheb",
};

var personDTO = Mapper.Map<Person, PersonDTO>(person);
و خروجی به شکل زیر میشه

نکته: توجه کنید این فقط یک مثال بود و این کار رو با روش‌های دیگه هم میشه انجام داد مثلا MapFrom  و...
نکته: میدان دید Value Resolver‌ها سراسری نیست و باید به ازای هر نگاشتی اونو معرفی کنیم.

Custom Value Formatters
فرض کنید تاریخ رو در بانک، به صورت میلادی ذخیره کرده‌اید و می‌خواهید سمت View به صورت شمسی نمایش بدید. بنابراین در مبدا ویژگی بنام MiladiDate از نوع DateTime دارید و در مقصد ویژگی بنام ShamsiDate از نوع String. هنگام نگاشت، AutoMapper  به صورت پیش فرض ToString رو فراخونی میکنه که بدرد ما نمیخوره و...
برای این کار میشه  از Value Formatter استفاده کرد با پیاده سازی اینترفیس IValueFormatter.
public class ShamsiFormatter:IValueFormatter
    {
        public string FormatValue(ResolutionContext context)
        {
            return ToShamsi(context.SourceValue.ToString());
        }
    }
نحوه استفاده
Mapper.CreateMap<Person, PersonDTO>().ForMember(
            des => des.ShamsiDate, op => op.AddFormatter<ShamsiFormatter>());
مطالب
اجزاء معماری سیستم عامل اندروید (قسمت اول :: امنیت سازمانی پروژه‌های اندرویدی) :: بخش هشتم
در این مدت (قسمت‌های قبلی آموزش)، ما به اپلیکیشن‌های تلفن همراه، از دیدگاه توسعه دهندگان اندرویدی، به صورت فردی نگاه کردیم. اگرچه من بر این باورم که توسعه دهندگان فردی یا شرکت‌های توسعه دهنده کوچک‌تر، بیشتر از توسعه دهندگان کسب‌وکار هستند؛ بنابراین تمرکز بر روی یک شرکت توسعه دهنده بسیار مفید خواهد بود و چالش‌های منحصر به فردی وجود دارند که با آن روبرو می‌شویم!

شاید وسوسه شوید که از این بخش صرف نظر کنید؛ اما با این حال من شما را ترغیب می‌کنم که این را در نظر بگیرید که اکثر شرکت‌ها این روزها به برون سپاری توسعه کار خود نگاه می‌کنند. شاید برای یک شرکت یا کسب و کار، وجود یک شخص توسعه دهنده‌ی اندرویدی که در خانه کار کند مناسب‌تر باشد تا درون یک تیم؛ مگر اینکه خودش بخواهد در تیم باشد و تمرکز اصلی شرکت روی این موضوع باشد و وجود آن فرد در تیم به کسب‌وکار، کمک بیشتری کند.
من تجارت‌های بسیاری را در حالت برون سپاری کار خود برای افراد یا شرکت‌های کوچک دیده‌ام، فقط به این دلیل که آن‌ها در مورد مدیریت تیم توسعه تلفن همراه، نگران نیستند؛ زیرا که به مدیریت خاصی احتیاج ندارند. با این حال، یک نکته مهم این است که وقتی در شرکت کار می‌کنید با اطلاعات سازمانی بسیار مهمی سروکار دارید و دیگر نگران از دست دادن اطلاعات شخصی خود نیستید!
 برای مثال: در یک محیط سازمانی، احتمال اینکه شما با اطلاعات محرمانه‌ای برخورد داشته باشید (مانند اسرار تجاری شرکت، اطلاعات مالی، یا حتی گواهینامه‌های سری مربوط به سرور مرکزی اپلیکیشن) بسیار بیشتر از زمانی است که شما با یک برنامه معمولی و ساده که به عموم مردم عرضه می‌شود در ارتباط باشید. علاوه بر این، برنامه شما می‌تواند به هدفی دیگر تبدیل شود به این دلیل که، بسیاری از حملات اندرویدی به دلیل سطوح پایین امنیتی، جذب این نوع حملات می‌شوند.
 بیایید ابتدا نگاهی به برخی از تفاوت‌های کلیدی اپلیکیشن‌های تجاری در مقایسه با اپلیکیشن‌های فردی بیاندازیم تا به وضوح این موضوع برایمان روشن شود.
مفهوم Connectivity در امنیت سازمانی برنامه ها:
برقراری اتصال از راه دور به برنامه‌ها در محیط کسب و کار از طریق ریموت شدن به سیستم‌های سازمانی در سال‌های اخیر یکی از مسائلی ست که براحتی برای همه قابل لمس می‌باشد و پرسنل عموما از راه دور و بدون توجه به نکات امنیتی، به سرورها و منابع مرکزی سیستمی شرکت متصل می‌شوند. پشتیبانی‌های از راه دور و برون سپاری به افرادی که آنها را نمی‌بینیم و صلاحیت امنیتی کار آنها برای ما نامشخص است از مواردی هستند که مدیران شرکت‌ها و سازمان‌های بزرگ به کاربران خود اجازه این کار را می‌دهند.
این بدین معناست که مدیران شبکه، راه عبور از فایروال‌ها را برای کاربران باز می‌کنند و کاربران بدون هیچ گونه احراز هویتی قادر به اتصال و ورود به هرگونه پورتی از منابع سرور خواهند بود! برای رفع این مشکل مدیران شبکه‌ها یک راه ارتباطی ایمن‌تر و خصوصی (VPN) را بین کاربران و منابع سرور ایجاد می‌کنند تا کاربران از راه دور بدون هیچ احراز هویتی وارد شده و فعالیت نمایند. به تصویر زیر توجه نمایید:

مطالب
زیر نویس فارسی ویدیوهای ساخت برنامه‌های مترو توسط سی شارپ و XAML - قسمت اول

سایت pluralsight ویدیوهای آموزشی بسیار با کیفیتی را در مورد مباحث مختلف دات نت تا بحال تهیه کرده و تقریبا هر موضوع جدیدی هم که اضافه می‌شود، بلافاصله یک سری جدید را تهیه می‌کنند. مدرسین انتخابی هم عموما افراد نامدار و باسوادی هستند.
پروژه‌ای رو در سایت کدپلکس شروع کردم جهت تهیه زیرنویس فارسی برای این ویدیوها:


این کار نسبت به کار تهیه زیرنویس‌های فارسی موجود برای فیلم‌های انگلیسی کار سخت‌تری است به چند دلیل:
- اسکریپت آماده‌ای وجود ندارد. کار شنیداری است.
- زمانبندی آماده‌ای وجود ندارد.
- مباحث تخصصی است.
- مدرس از ثانیه اول ویدیو تا ثانیه آخر آن حرف می‌زند!

برای مثال جهت تهیه زیرنویس‌های فارسی فیلم‌های انگلیسی عموما به سایت‌هایی مانند subscene.com مراجعه می‌شود. یک زیرنویس یا به قولی اسکریپت آماده یافت شده و شروع به ترجمه می‌شود. متن آماده است. زمانبندی آماده است و فقط کار ترجمه باقی می‌ماند.
اما در مورد ویدیوهای آموزشی انگلیسی خیر. به همین جهت در این زمینه کار آنچنانی تابحال صورت نگرفته.
کار زمانبری است. فعلا رکورد من برای هر سه دقیقه ویدیوی آموزشی که مدرس از ثانیه اول تا آخر آن حرف می‌زند، 40 دقیقه کار تهیه زیر نویس فارسی زمانبندی شده است.

سری جدیدی رو که شروع کردم تحت عنوان «Building Windows 8 Metro Apps in C# and XAML» در سایت pluralsight ارائه شده.
فعلا قسمت اول آن زیرنویس دار شده و از اینجا قابل دریافت است. برای مشاهده آن‌ها برنامه با کیفیت و رایگان KMPlayer توصیه می‌شود.

لیست ویدیوهای قسمت اول آن به شرح زیر است:

Building Windows 8 Metro Apps in C# and XAML 
Overview 00:50:41
This modules provides an overview of how to develop Windows 8 Metro style applications in C# and XAML.

Introduction
XAML and Codebehind
Asynchronous APIs
Demo: Asynchronous APIs
Files and Networking
Demo: Requesting Capabilities
Integrating with Windows 8
WinRT and .NET
Summary

کلمه سی شارپ در این قسمت کمی غلط انداز است. بیشتر بحث و توضیح است تا کد نویسی. بنابراین برای عموم قابل استفاده است. خصوصا نگاهی دارد به تازه‌های ویندوز 8 از دیدگاه برنامه نویس‌ها مانند سطوح دسترسی برنامه‌های مترو، معرفی Charms ، نحوه به اشتراک گذاری اطلاعات در بین برنامه‌های مترو نصب شده، برای مثال جایی که دیگر Clipboard سابق وجود ندارد و مواردی از این دست.

5 قسمت دیگر این مبحث باقیمانده که هر زمان تکمیل شد، خبرش رو خواهید شنید و تقریبا از این پس این سایت به همین ترتیب جلو خواهد رفت. فکر می‌کنم اینطوری مفیدتر باشد. هر از چندگاهی یک مبحث جدید زیرنویس دار شده را می‌توانید مشاهده کنید.

اگر علاقمند بودید می‌تونید در این پروژه شرکت کنید و یک موضوع جدید و مستقل را برای تهیه زیرنویس شروع کنید. یا حداقل اگر پس از مشاهده این سری آماده شده، اصلاحی را انجام دادید، می‌تونید اون رو برای اعمال در اینجا ارسال کنید.