مطالب
تعیین اعتبار کردن یک عبارت SQL

سؤال: چگونه می‌توان یک کوئری را تعیین اعتبار کرد بدون اینکه نتیجه‌ی اجرای آن برای ما اهمیتی داشته باشد یا دیتابیس را به هم بریزد؟

روش انجام این‌کار در اس کیوال سرور به صورت زیر است:

SET NOEXEC ON
GO
عبارات اس کیوال ما در اینجا قرار خواهند گرفت
GO
SET NOEXEC OFF
GO
مطابق راهنمای اس کیوال سرور، SET NOEXEC سبب کامپایل کوئری‌های پس از آن شده ولی آن‌ها‌را اجرا نخواهد کرد. همچنین SET PARSEONLY ON فقط syntax یک کوئری را بررسی کرده و خطاهای حاصل را نمایش می‌دهد (بدون اجرا کوئری، بدون کامپایل آن).

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

مطالب
شروع کار با ASP.NET Web API 2
HTTP تنها برای به خدمت گرفتن صفحات وب نیست. این پروتکل همچنین پلتفرمی قدرتمند برای ساختن API هایی است که سرویس‌ها و داده را در دسترس قرار می‌دهند. این پروتکل ساده، انعطاف پذیر و در همه جا حاضر است. هر پلتفرمی که فکرش را بتوانید بکنید کتابخانه ای برای HTTP دارد، بنابراین سرویس‌های HTTP می‌توانند بازه بسیار گسترده ای از کلاینت‌ها را پوشش دهند، مانند مرورگرها، دستگاه‌های موبایل و اپلیکیشن‌های مرسوم دسکتاپ.

ASP.NET Web API فریم ورکی برای ساختن API‌های وب بر روی فریم ورک دات نت است. در این مقاله با استفاده از این فریم ورک، API وبی خواهیم ساخت که لیستی از محصولات را بر می‌گرداند. صفحه وب کلاینت، با استفاده از jQuery نتایج را نمایش خواهد داد.


یک پروژه Web API بسازید

در ویژوال استودیو 2013 پروژه جدیدی از نوع ASP.NET Web Application بسازید و نام آن را "ProductsApp" انتخاب کنید.

در دیالوگ New ASP.NET Project قالب Empty را انتخاب کنید و در قسمت "Add folders and core references for" گزینه Web API را انتخاب نمایید.

می توانید از قالب Web API هم استفاده کنید. این قالب با استفاده از ASP.NET MVC صفحات راهنمای API را خواهد ساخت. در این مقاله از قالب Empty استفاده میکنیم تا تمرکز اصلی، روی خود فریم ورک Web API باشد. بطور کلی برای استفاده از این فریم ورک لازم نیست با ASP.NET MVC آشنایی داشته باشید.

افزودن یک مدل

یک مدل (model) آبجکتی است که داده اپلیکیشن شما را معرفی می‌کند. ASP.NET Web API می‌تواند بصورت خودکار مدل شما را به JSON, XML و برخی فرمت‌های دیگر مرتب (serialize) کند، و سپس داده مرتب شده را در بدنه پیام HTTP Response بنویسد. تا وقتی که یک کلاینت بتواند فرمت مرتب سازی داده‌ها را بخواند، می‌تواند آبجکت شما را deserialize کند. اکثر کلاینت‌ها می‌توانند XML یا JSON را تفسیر کنند. بعلاوه کلاینت‌ها می‌توانند فرمت مورد نظرشان را با تنظیم Accept header در پیام HTTP Request مشخص کنند.

بگذارید تا با ساختن مدلی ساده که یک محصول (product) را معرفی میکند شروع کنیم.

کلاس جدیدی در پوشه Models ایجاد کنید.

نام کلاس را به "Product" تغییر دهید، و خواص زیر را به آن اضافه کنید.

namespace ProductsApp.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

افزودن یک کنترلر

در Web API کنترلر‌ها آبجکت هایی هستند که درخواست‌های HTTP را مدیریت کرده و آنها را به اکشن متدها نگاشت می‌کنند. ما کنترلری خواهیم ساخت که می‌تواند لیستی از محصولات، یا محصولی بخصوص را بر اساس شناسه برگرداند. اگر از ASP.NET MVC استفاده کرده اید، با کنترلرها آشنا هستید. کنترلرهای Web API مشابه کنترلر‌های MVC هستند، با این تفاوت که بجای ارث بری از کلاس Controller از کلاس ApiController مشتق می‌شوند.

کنترلر جدیدی در پوشه Controllers ایجاد کنید.

در دیالوگ Add Scaffold گزینه Web API Controller - Empty را انتخاب کرده و روی Add کلیک کنید.

در دیالوگ Add Controller نام کنترلر را به "ProductsController" تغییر دهید و روی Add کلیک کنید.

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

using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace ProductsApp.Controllers
{
    public class ProductsController : ApiController
    {
        Product[] products = new Product[] 
        { 
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public IHttpActionResult GetProduct(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }
}
برای اینکه مثال جاری را ساده نگاه داریم، محصولات مورد نظر در یک آرایه استاتیک ذخیره شده اند. مسلما در یک اپلیکیشن واقعی برای گرفتن لیست محصولات از دیتابیس یا منبع داده ای دیگر کوئری می‌گیرید.

کنترلر ما دو متد برای دریافت محصولات تعریف می‌کند:

  • متد GetAllProducts لیست تمام محصولات را در قالب یک <IEnumerable<Product بر می‌گرداند.
  • متد GetProductById سعی می‌کند محصولی را بر اساس شناسه تعیین شده پیدا کند.

همین! حالا یک Web API ساده دارید. هر یک از متدهای این کنترلر، به یک یا چند URI پاسخ می‌دهند:

 URI  Controller Method
api/products/  GetAllProducts
 api/products/id/  GetProductById

برای اطلاعات بیشتر درباره نحوه نگاشت درخواست‌های HTTP به اکشن متدها توسط Web API به این لینک مراجعه کنید.


فراخوانی Web API با جاوا اسکریپت و jQuery

در این قسمت یک صفحه HTML خواهیم ساخت که با استفاده از AJAX متدهای Web API را فراخوانی می‌کند. برای ارسال درخواست‌های آژاکسی و بروز رسانی صفحه بمنظور نمایش نتایج دریافتی از jQuery استفاده میکنیم.

در پنجره Solution Explorer روی نام پروژه کلیک راست کرده و گزینه Add, New Item را انتخاب کنید.

در دیالوگ Add New Item قالب HTML Page را انتخاب کنید و نام فایل را به "index.html" تغییر دهید.

حال محتوای این فایل را با لیست زیر جایگزین کنید.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Product App</title>
</head>
<body>

  <div>
    <h2>All Products</h2>
    <ul id="products" />
  </div>
  <div>
    <h2>Search by ID</h2>
    <input type="text" id="prodId" size="5" />
    <input type="button" value="Search" onclick="find();" />
    <p id="product" />
  </div>

  <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
  <script>
    var uri = 'api/products';

    $(document).ready(function () {
      // Send an AJAX request
      $.getJSON(uri)
          .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
              // Add a list item for the product.
              $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
          });
    });

    function formatItem(item) {
      return item.Name + ': $' + item.Price;
    }

    function find() {
      var id = $('#prodId').val();
      $.getJSON(uri + '/' + id)
          .done(function (data) {
            $('#product').text(formatItem(data));
          })
          .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
          });
    }
  </script>
</body>
</html>
راه‌های مختلفی برای گرفتن jQuery وجود دارد، در این مثال از Microsoft Ajax CDN استفاده شده. می‌توانید این کتابخانه را از http://jquery.com دانلود کنید و بصورت محلی استفاده کنید. همچنین قالب پروژه‌های  Web API این کتابخانه را به پروژه نیز اضافه می‌کنند.


گرفتن لیستی از محصولات

برای گرفتن لیستی از محصولات، یک درخواست HTTP GET به آدرس "api/products/" ارسال کنید.

تابع getJSON یک درخواست آژاکسی ارسال می‌کند. پاسخ دریافتی هم آرایه ای از آبجکت‌های JSON خواهد بود. تابع done در صورت موفقیت آمیز بودن درخواست، اجرا می‌شود. که در این صورت ما DOM را با اطلاعات محصولات بروز رسانی می‌کنیم.

$(document).ready(function () {
    // Send an AJAX request
    $.getJSON(apiUrl)
        .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
                // Add a list item for the product.
                $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
        });
});

گرفتن محصولی مشخص

برای گرفتن یک محصول توسط شناسه (ID) آن کافی است یک درخواست HTTP GET به آدرس "api/products/id/" ارسال کنید.

function find() {
    var id = $('#prodId').val();
    $.getJSON(apiUrl + '/' + id)
        .done(function (data) {
            $('#product').text(formatItem(data));
        })
        .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
        });
}
برای این کار هنوز از getJSON برای ارسال درخواست آژاکسی استفاده می‌کنیم، اما اینبار شناسه محصول را هم به آدرس درخواستی اضافه کرده ایم. پاسخ دریافتی از این درخواست، اطلاعات یک محصول با فرمت JSON است.


اجرای اپلیکیشن

اپلیکیشن را با F5 اجرا کنید. صفحه وب باز شده باید چیزی مشابه تصویر زیر باشد.

برای گرفتن محصولی مشخص، شناسه آن را وارد کنید و روی Search کلیک کنید.

اگر شناسه نامعتبری وارد کنید، سرور یک خطای HTTP بر می‌گرداند.


استفاده از F12 برای مشاهده درخواست‌ها و پاسخ ها

هنگام کار با سرویس‌های HTTP، مشاهده‌ی درخواست‌های ارسال شده و پاسخ‌های دریافتی بسیار مفید است. برای اینکار می‌توانید از ابزار توسعه دهندگان وب استفاده کنید، که اکثر مرورگرهای مدرن، پیاده سازی خودشان را دارند. در اینترنت اکسپلورر می‌توانید با F12 به این ابزار دسترسی پیدا کنید. به برگه Network بروید و روی Start Capturing کلیک کنید. حالا صفحه وب را مجددا بارگذاری (reload) کنید. در این مرحله اینترنت اکسپلورر ترافیک HTTP بین مرورگر و سرور را تسخیر می‌کند. می‌توانید تمام ترافیک HTTP روی صفحه جاری را مشاهده کنید.

به دنبال آدرس نسبی "api/products/" بگردید و آن را انتخاب کنید. سپس روی Go to detailed view کلیک کنید تا جزئیات ترافیک را مشاهده کنید. در نمای جزئیات، می‌توانید header‌ها و بدنه درخواست‌ها و پاسخ‌ها را ببینید. مثلا اگر روی برگه Request headers کلیک کنید، خواهید دید که اپلیکیشن ما در Accept header داده‌ها را با فرمت "application/json" درخواست کرده است.

اگر روی برگه Response body کلیک کنید، می‌توانید ببینید چگونه لیست محصولات با فرمت JSON سریال شده است. همانطور که گفته شده مرورگرهای دیگر هم قابلیت‌های مشابهی دارند. یک ابزار مفید دیگر Fiddler است. با استفاده از این ابزار می‌توانید تمام ترافیک HTTP خود را مانیتور کرده، و همچنین درخواست‌های جدیدی بسازید که این امر کنترل کاملی روی HTTP headers به شما می‌دهد.


قدم‌های بعدی

  • برای یک مثال کامل از سرویس‌های HTTP که از عملیات POST,PUT و DELETE پشتیبانی می‌کند به این لینک مراجعه کنید.
  • برای اطلاعات بیشتر درباره طراحی واکنش گرا در کنار سرویس‌های HTTP به این لینک مراجعه کنید، که اپلیکیشن‌های تک صفحه ای (SPA) را بررسی می‌کند.
نظرات مطالب
تاریخ شمسی با Extension Method برای DateTime
ممنون بابت جواب. اون یکی رو با راهنمایی شما حل کردم. ممنون. یه مشکل دیگه . من در این پروژه از Telerik Extension استفاده کردم . خودش این امکانو داره که بتونیش Globalization کنی . من این CultureInfo رو که شما درست کردینو بهش میدم اما نصفه نیمه شده. مثلا نوشته 27 مرداد 2013؟
قسمت بالاشم که اسم ماه و سال هست، نوشته مثلا مرداد 2013. در کل سال رو به همون صورت میلادی نشون میده و بقیه رو به شمسی. این CultureInfo شما چیزی دیگه‌ای کم نداره که اونم رو هم مقدار دهی کنیم، تکمیل بشه؟ من احساس میکنم همه توابع و خصوصیت‌هاش مقدار دهی نشده. در ضمن با اینکه تقویمشو Persian Calender دادیم پس چرا هنوز داره با همون میلادی روز‌ها و بقیه رو حساب میکنه. تازه خلاصه اسم روز‌ها رو هم نشون نمیده. جالب اینجاست که وقتی من تاریخ سیستم خودمو فارسی میکنم مثلا این چیزاشو نمایش میده. چیزایی مثله خلاصه اسم روز. اگه بشه اینو یه جورایی فارسی کرد خیلی خوب میشه. هم کلی تمپلیت داره. هم کلی افکت خوب داره. هم خود تلریک یه نوع Project template برای MVC4 درست کرده که وقتی باهاش پروژتونو ایجاد میکنید دیگه خودش اتوماتیک هرجا فیلدتونو تاریخ تعریف کنید خیلی باحال همه چیز رو میاره. ببینین میتونین یه کاریش بکنین. باز ممنون.

مطالب
معرفی نسخه غیر رسمی SSCEVSTools for Visual Studio 2013
با هر بار عرضه‌ی نسخه‌های جدید ویژوال استادیو، علاوه بر اضافه شدن امکانات جدید، برخی از امکانات هم به دلایل نامعلومی از این نرم افزار حذف می‌شوند. در Visual Studio 2012 امکان بسیار کارآمد Setup and Deployment حذف گردید و این بار  برخلاف انتظار در Visual Studio 2013 با عدم پشتیبانی از Sql Server Compact مواجه شدیم و هنور دلایل این کار از سوی تیم ویژوال استادیو توضیح داده نشده است. شاید مایکروسافت در حال توسعه نسخه NoSql جدیدی برای جایگزینی باشد.

می توانید از ابزار SQL Server Compact Toolbox استفاده نمایید که کارایی خوبی ندارد و بیشتر یک مکمل است. اما راهی برای بازگشت این ابزار به Visual Studio 2013 وجود دارد؟

قابلیت Data Designer Extensibility
در نگارش‌های مختلف ویژوال استادیو امکانی به نام DDEX Provider وجود دارد که توسط آن می‌توانید یک Data Designer جدید را به ویژوال استادیو اضافه نمایید. در واقع اگر از پنجره Server Explorer بر روی Data Connections راست کلیک و یک کانکشن جدید بسازید، لیست Data Source‌های پیش فرض ویژوال استادیو به شما نشان داده می‌شود که به کمک همین قابلیت DDEX به ویژوال استادیو اضافه شده است. با این قابلیت، امکان اضافه نمون یک Data Designer برای یک پایگاه داده نیز وجود دارد. از آدرس  Data Designer Extensibility (DDEX) SDK می توانید نحوه تولید و رجیستر کردن یک DDEX Provider را بیاموزید. برای مثال رجیستری زیر IBM DB2 Data Provider را به ویژوال استادیو اضافه می‌نماید
HKLM
{
   %REGROOTBEGIN%
 
   'DataProviders'
   {
      '{6085DDE2-2EE1-4768-82C3-5425D9B98DAD}' = s 'IBM DB2 Provider'
      {
         val 'DisplayName' = s 'Provider_DisplayName, IBM.DB2.Resources'
         val 'ShortDisplayName' = s 'Provider_ShortDisplayName, IBM.DB2.Resources'
         val 'Description' = s 'Provider_Description, IBM.DB2.Resources'
         val 'FactoryService'= s'{45E1413D-896C-4a2a-A75C-1CBCA51C80CB}'
         val 'Technology' = s '{6565551F-A496-45f3-AFFB-D1AECA082824}'
         val 'InvariantName' = s 'IBM.DB2'
         val 'PlatformVersion' = s '2.0'
 
         'SupportedObjects'
         {
            'IVsDataViewSupport'
            'IVsDataObjectSupport'
            'IVsDataConnectionUIControl'
            'IVsDataConnectionProperties'
            'IVsDataConnectionSupport'
         }
      }
   }
 
   'Services'
   {
      '{45E1413D-896C-4a2a-A75C-1CBCA51C80CB}' = s '{7B7F1923-D8F9-430f-9FA7-7919677E5EAC}'
      {
         val 'Name' = 'IBM DB2 Provider Object Factory'
      }
   }
 
   'Packages'
   {
      '{7B7F1923-D8F9-430f-9FA7-7919677E5EAC}' = 'DB2 Package'
      {
         val 'InProcServer32' = s 'mscoree.dll'
         val 'Class' = s 'IBM.DB2.DB2Package'
         val 'Codebase' = s '%MODULE%'
 
         'SatelliteDll'
         {
             val 'Path' = s '%PATH%'
             val 'DllName' = s 'IBM.DB2UI.DLL'
         }
   }
 
   %REGROOTEND%
}
ابزار SSCEVSTools for Visual Studio 2013
برای اضافه نمودن Sql Server Compact Data Provider به Visual Studio  2013 از نسخه قبلی SSCEVSTools که برای Visual Studio 2012 عرضه شده است استفاده می‌کنیم. در واقع این ابزار یک DDEX Provider را به ویژوال استادیو برای Sql  Server Compact اضافه می‌کند. اما این نصب کننده، برای نسخه‌ی قبل، تهیه شده است و امکان نصب آن بر روی Visual Studio 2013 نمی‌باشد. یک راهکار عملی، دسترسی به فایل‌ها و رجیستری‌های موجود در این نصب کننده و تولید نصب کننده جدیدی می‌باشد.
 
دسترسی به محتوی فایل‌های Setup
ابزار Orca در Windows SDK برای ویرایش فایل‌های نصب کننده توسط مایکروسافت تولید شده است که امکان مشاهده تمامی جزئیات آن را فراهم می‌نماید. ابزار قبلی، شامل فایل‌های dll و رجیستری است و امکان اتصال به Sql Server Compact را به ویژوال استادیو اضافه می‌نمود. 
حال با یک برنامه Setup ساز، فایل‌ها و رجیستری را برای Visual Studio 2013 تنظیم نموده و با نصب ابزار جدید، دوباره امکان استفاده از Sql Server Compact در Visual Studio 2013 میسر می‌شود.
برای نصب این ابزار، آن را از گالری ویژوال استادیو به نام  SSCEVSTools for Visual Studio 2013  دانلود نمایید.
البته چون این ابزار بصورت غیر رسمی تولید و عرضه شده است گاهی اوقات به صورت خودکار از لیست Data Source‌ها حذف شده که لازم است آن را حذف و مجددا نصب نمایید.

اگر مایل به بازگشت و کار بر روی نسخه جدید Sql Server Compact 5 هستید اینجا در Visual Studio UserVoice رای دهید.

مطالب
آشنایی با تابع EOMONTH در SQL Server
گاهی اوقات لازم است، تاریخ آخرین روز ماه جاری یا دو ماه بعد‌تر یا یک ماه قبل‌تر و غیرو... را نیاز داشته باشیم. SQL Server در نسخه 2008 خود تابعی ارائه داده است، که تاریخ آخرین روز ماه را برمی گرداند. و Syntax آن به شرح ذیل می‌باشد:
EOMONTH ( start_date [, month_to_add ] )
این تابع دو پارامتر دریافت می‌کند، اولین پارامتر یک فرمت تاریخ می‌پذیرد، دومین پارامتر، اختیاری است و یک عدد می‌پذیرد و بیانگر تعداد ماه بعد از تاریخ یا تعداد ماه قبل از تاریخ،پارامتر اول می‌باشد.
با چند مثال نحوه استفاده از تابع EOMONTH  را می‌آموزیم:
مثال اول:
SELECT EOMONTH('20110201') as 'آخرین روز ماه فوریه در سال 2011';
SELECT EOMONTH('20120201') as 'آخرین روز ماه فوریه در سال 2012';
SELECT EOMONTH('20130201') as 'آخرین روز ماه فوریه در سال 2013';
خروجی بصورت زیر می‌باشد:


مثال دوم:
یافتن آخرین روز دو ماه بعدتر از تاریخ جاری
SELECT EOMONTH(GETDATE(),2) as 'آخرین روز ماه ژانویه در سال 2013';
خروجی بصورت زیر خواهد بود:


مثال سوم:
یافتن آخرین روز دو ماه قبل‌تر از تاریخ جاری:
SELECT EOMONTH(GETDATE(),-2) as 'آخرین روز ماه سپتامبر'
خروجی :

موفق باشید
مطالب
فایل‌های chm و مشکل فارسی - قسمت اول

همانطور که مطلع هستید از ویندوز ویستا به بعد، فرمت قدیمی فایل‌های راهنمای ویندوز (فایل‌های hlp) منسوخ شده تلقی می‌شود و فرمت پیشنهادی، chm است. نرم افزارهای زیادی برای تهیه فایل‌های compiled html help یا همان chm های معروف وجود دارند که معروفترین آن‌ها برنامه‌ی Help & Manual است.
اما تمام این برنامه‌ها در حقیقت پوسته‌ای هستند برای برنامه‌ی رایگان html help work shop مایکروسافت و در نهایت از کامپایلر آن استفاده می‌کنند. بنابراین چرا از برنامه‌ی رایگان اصلی استفاده نشود؟

اگر تا به حال با html help work shop کار نکرده‌اید، در ادامه مروری سریع بر آن خواهیم داشت:

الف) درست کردن فایل‌های صفحات راهنما
برنامه‌ی Help & Manual ایی که معرفی شد و تمام نمونه‌های مشابه آن، تنها کار مهمی را که انجام می‌دهند این است که شما را از یک html editor بی‌نیاز می‌کنند. بنابراین زمانیکه می‌خواهیم از برنامه‌ی اصلی html help work shop استفاده کنیم نیاز به یک html editor خارجی برای تهیه فایل‌های راهنما خواهیم داشت. مثلا مرحوم front page یا نگارش جدید آن به نام Microsoft expression web یا Dreamweaver یا Aptana یا حتی notepad !
در اینجا تنها مشخص کردن نوع encoding نمایش صفحه برای صحیح نمایش داده شدن متون فارسی کافی است. اما این تمام ماجرا نیست.

ب) کامپایل کردن فایل‌های راهنمای ایجاد شده
برای این منظور بجای آپلود بیش از 30 تصویر جهت توضیحات قدم به قدم نحوه‌ی انجام این‌کار، یک فایل ویدیویی درست کرده‌ام که آن‌‌را از آدرس زیر می‌توانید دریافت کنید.
دریافت فایل

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

در قسمت دوم، نحوه‌ی رفع این دو مشکل (مشکل جستجوی عبارات فارسی و مشکل عنوان‌های به هم ریخته) را بررسی خواهیم کرد.

ادامه دارد ...

مطالب
حذف سریع رکورد های یک لیست SharePoint با NET. در PowerShell
لطفا توجه فرمایید که جالب‌ترین قسمت این مقاله قابلیت استفاده از کلاس‌های دات نت در دل PowerShell می‌باشد. که در قسمت چهارم کد‌ها مشاهده می‌فرمایید.
حذف تمام رکورد‌های یک لیست شیرپوینت از طریق رابط کاربری SharePoint  مسیر نمیباشد و لازم است برای آن چند خط کد نوشته شود که می‌توانید آن را با console و جالب‌تر از آن با  PowerShell   اجرا کنید.
1- ساده‌ترین روش حذف رکورد‌های شیرپوینت را در روبرو مشاهده می‌فرمایید که به ازای حذف هر رکورد یک رفت و برگشت به پایگاه انجام می‌شود
SPList list = mWeb.GetList(strUrl);
if (list != null)
{
    for (int i = list.ItemCount - 1; i >= 0; i--)
    {
        list.Items[i].Delete();
    }
    list.Update();
}
2- با استفاده از  SPWeb.ProcessBatchData در کد زیر می‌توانیم با سرعت بیشتر و هوشمندانه‌تری، حذف تمام رکورد‌ها را در یک عمل انجام دهیم
public static void DeleteAllItems(string site, string list)
{
    using (SPSite spSite = new SPSite(site))
    {
        using (SPWeb spWeb = spSite.OpenWeb())
        {
            StringBuilder deletebuilder = BatchCommand(spWeb.Lists[list]);
            spSite.RootWeb.ProcessBatchData(deletebuilder.ToString());
        }
    }
}

private static StringBuilder BatchCommand(SPList spList)
{
    StringBuilder deletebuilder= new StringBuilder();
    deletebuilder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
    string command = "<Method><SetList Scope=\"Request\">" + spList.ID +
        "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";

    foreach (SPListItem item in spList.Items)
    {
        deletebuilder.Append(string.Format(command, item.ID.ToString()));
    }
    deletebuilder.Append("</Batch>");
    return deletebuilder;
}
3- در قسمت زیر همان روش batch  قبلی را مشاهده می‌فرمایید که با تقسیم کردن batch  ها به تکه‌های 1000 تایی کارایی آن را بالا برده ایم
// We prepare a String.Format with a String.Format, this is why we have a {{0}} 
   string command = String.Format("<Method><SetList Scope=\"Request\">{0}</SetList><SetVar Name=\"ID\">{{0}}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar><SetVar Name=\"owsfileref\">{{1}}</SetVar></Method>", list.ID);
   // We get everything but we limit the result to 100 rows 
   SPQuery q = new SPQuery();
   q.RowLimit = 100;

   // While there's something left 
   while (list.ItemCount > 0)
   {
    // We get the results 
    SPListItemCollection coll = list.GetItems(q);

    StringBuilder sbDelete = new StringBuilder();
    sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");

    Guid[] ids = new Guid[coll.Count];
    for (int i=0;i<coll.Count;i++)
    {
     SPListItem item = coll[i];
     sbDelete.Append(string.Format(command, item.ID.ToString(), item.File.ServerRelativeUrl));
     ids[i] = item.UniqueId;
    }
    sbDelete.Append("</Batch>");

    // We execute it 
    web.ProcessBatchData(sbDelete.ToString());

    //We remove items from recyclebin
    web.RecycleBin.Delete(ids);

    list.Update();
   }
  }
4- در این قسمت به جالب‌ترین و آموزنده‌ترین قسمت این مطلب می‌پردازیم و آن import کردن namespace‌ها و ساختن object‌های دات نت در دل PowerShell هست که می‌توانید به راحتی با مقایسه با کد قسمت قبلی که در console نوشته شده است، آن‌را فرا بگیرید.
برای فهم script پاور شل زیر کافیست به چند نکته ساده زیر دقت کنید 
  • ایجاد متغیر‌ها به سادگی با شروع نوشتن نام متغیر با $ و بدون تعریف نوع آن‌ها انجام می‌شود
  • write-host حکم  write را دارد و واضح است که نوشتن تنهای آن برای ایجاد یک line break می‌باشد. 
  • کامنت کردن با # 
  • عدم وجود semi colon  برای اتمام فرامین
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")

write-host 

# Enter your configuration here
$siteUrl = "http://mysharepointsite.example.com/"
$listName = "Name of my list"
$batchSize = 1000

write-host "Opening web at $siteUrl..."

$site = new-object Microsoft.SharePoint.SPSite($siteUrl)
$web = $site.OpenWeb()
write-host "Web is: $($web.Title)"

$list = $web.Lists[$listName];
write-host "List is: $($list.Title)"

while ($list.ItemCount -gt 0)
{
  write-host "Item count: $($list.ItemCount)"

  $batch = "<?xml version=`"1.0`" encoding=`"UTF-8`"?><Batch>"
  $i = 0

  foreach ($item in $list.Items)
  {
    $i++
    write-host "`rProcessing ID: $($item.ID) ($i of $batchSize)" -nonewline

    $batch += "<Method><SetList Scope=`"Request`">$($list.ID)</SetList><SetVar Name=`"ID`">$($item.ID)</SetVar><SetVar Name=`"Cmd`">Delete</SetVar><SetVar Name=`"owsfileref`">$($item.File.ServerRelativeUrl)</SetVar></Method>"

    if ($i -ge $batchSize) { break }
  }

  $batch += "</Batch>"

  write-host

  write-host "Sending batch..."

  # We execute it 
  $result = $web.ProcessBatchData($batch)

  write-host "Emptying Recycle Bin..."

  # We remove items from recyclebin
  $web.RecycleBin.DeleteAll()

  write-host

  $list.Update()
}

write-host "Done."


نظرات اشتراک‌ها
تبدیلگر ایران سیستم به یونیکد
مرسی با این کد کاملا صحیح کاراکترها تبدیل میشه. اما همچنان زمان آپلود فایل خطا میداد که مقدار فیلد شماره لیست در فایل بیمه شدگان صحیح نیست.
یک راه دیگه رو امتحان کردم که بالاخره جواب داد! در فولدر DataBase برنامه تامین اجتماعی دو فایل DSKKAR00  و DSKWOR00 دیدم که فیلدها در آن‌ها تعریف شده بود ولی دیتا براشون ثبت نشده، حدس زدم که برنامه تامین اجتماعی هم از همین فایل‌ها استفاده میکنه.
من در برنامه خودم کد مربوط به ایجاد فایل رو حذف و آدرس این فایل‌ها رو دادم که دیتا در این فایل‌ها Insert بشه و مشکل حل شد و سایت فایل‌های من رو قبول کرد !
فایل راهنمای تامین اجتماعی که ساختار جدول‌های این فایل‌ها رو نوشته بود اشتباه بوده و نوع فیلدهایی که در اون فایل گفته بود در برنامه خودشون استفاده نشده و در سایت تامین اجتماعی هم قبول نمی‌کرد! 
نظرات مطالب
شروع کار با Angular Material ۲
از نسخه 2.0.beta-11، ماژول  MaterialModule حذف شده است. این ماژول تمامی کامپوننتهای پیاده سازی شده را جهت استفاده وارد می‌کرد. از این نسخه به بعد بایستی کامپوننتهای مورد استفاده یکی یکی وارد شوند. به عنوان مثال اگر در برنامه خود فقط از کامپوننت دکمه و چک باکس استفاده می‌کنیم، به شکل زیر عمل میکنیم. 
import {
  MatButtonModule,
  MatCheckboxModule
} from "@angular/material";
به جهت جلوگیری از شلوغی ماژول اصلی برنامه بهتر است ماژول دیگری به شکل زیر تعریف کنیم که کامپوننتهای مورد استفاده در برنامه را مدیریت میکند و ماژول اصلی برنامه تنها از این ماژول استفاده خواهد کرد. (این روش در راهنمای استفاده از Angular Material Design به عنوان یک روش مطرح شده است.)
import {MatButtonModule, MatCheckboxModule} from '@angular/material';

@NgModule({
  imports: [MatButtonModule, MatCheckboxModule],
  exports: [MatButtonModule, MatCheckboxModule],
})
export class MyOwnCustomMaterialModule { }
در این صورت کافی است در AppModule فقط MyOwnCustomMaterialModule را در قسمت imports ذکر کنیم.