دعوت به همکاری در شرکت سهند (استخدام شرکت سهند)

entity-framework-exceptional-detail-by-elmah
نرم افزار درخواستمزیت های نرم افزارپیاده سازی شده بصورت تحت وب و بدون نیاز به نصب روی سیستم کاربر و یا امکانات خاص جهت اجرای نرم افزار

در حین بروز استثناهای Entity framework، می‌توان توسط ابزارهای Logging متنوعی مانند ELMAH، جزئیات متداول آن‌ها را برای بررسی‌های آتی ذخیره کرد. اما این جزئیات فاقد SQL نهایی تولیدی و همچنین پارامترهای ورودی توسط کاربر یا تنظیم شده توسط برنامه هستند. برای اینکه بتوان این جزئیات را نیز ثبت کرد، می‌توان یک IDbCommandInterceptor جدید را طراحی کرد.

کلاس EfExceptionsInterceptor

در اینجا نمونه‌ای از یک پیاده سازی اینترفیس IDbCommandInterceptor را مشاهده می‌کنید. همچنین طراحی یک متد عمومی که می‌تواند به جزئیات SQL نهایی و پارامترهای آن دسترسی داشته باشد، در اینترفیس IEfExceptionsLogger ذکر شده‌است

public interface IEfExceptionsLogger
{
void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext);
}

using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;

namespace ElmahEFLogger
{
public class EfExceptionsInterceptor : IDbCommandInterceptor
{
private readonly IEfExceptionsLogger _efExceptionsLogger;

public EfExceptionsInterceptor(IEfExceptionsLogger efExceptionsLogger)
{
_efExceptionsLogger = efExceptionsLogger;
}

public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}

public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}

public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}

public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}

public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}

public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
}
}

تهیه یک پیاده سازی سفارشی از IEfExceptionsLogger توسط ELMAH

اکنون که ساختار کلی IDbCommandInterceptor سفارشی برنامه مشخص شد، می‌توان پیاده سازی خاصی از آن‌را جهت استفاده از ELMAH به نحو ذیل ارائه داد:

using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using Elmah;

namespace ElmahEFLogger.CustomElmahLogger
{
public class ElmahEfExceptionsLogger : IEfExceptionsLogger
{
/// <summary>
/// Manually log errors using ELMAH
/// </summary>
public void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext)
{
var ex = interceptionContext.OriginalException;
if (ex == null)
return;

var sqlData = CommandDumper.LogSqlAndParameters(command, interceptionContext);
var contextualMessage = string.Format(“{0}{1}OriginalException:{1}{2} {1}”, sqlData, Environment.NewLine, ex);

if (!string.IsNullOrWhiteSpace(contextualMessage))
{
ex = new Exception(contextualMessage, new ElmahEfInterceptorException(ex.Message));
}

try
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
catch
{
ErrorLog.GetDefault(null).Log(new Error(ex));
}
}
}
}

در اینجا شیء Command به همراه SQL نهایی تولید و پارامترهای مرتبط است. همچنین interceptionContext.OriginalException جزئیات عمومی استثنای رخ داده را به همراه دارد. می‌توان این اطلاعات را پس از اندکی نظم بخشیدن، به متد Raise مربوط به ELMAH ارسال کرد تا جزئیات بیشتری از استثنای رخ داده شده، در لاگ‌های آن ظاهر شوند.

استفاده از ElmahEfExceptionsLogger جهت طراحی یک Interceptor عمومی

public class ElmahEfInterceptor : EfExceptionsInterceptor
{
public ElmahEfInterceptor()
: base(new ElmahEfExceptionsLogger())
{ }
}

برای استفاده از ElmahEfExceptionsLogger و تهیه یک Interceptor عمومی، می‌توان با ارث بری از کلاس Interceptor ابتدای بحث شروع کرد و وهله‌ای از ElmahEfExceptionsLogger را به سازنده‌ی آن تزریق نمود (یکی از چندین روش ممکن). سپس برای استفاده از آن کافی است به ابتدای متد Application_Start فایل Global.asax.cs مراجعه و در ادامه سطر ذیل را اضافه نمود:

DbInterception.Add(new ElmahEfInterceptor());

پس از آن جزئیات کلیه استثناهای EF در لاگ‌های نهایی ELMAH به نحو ذیل ظاهر خواهند شد:

entity framework exceptional detail by elmah 2 - ثبت جزئیات استثناهای Entity framework توسط ELMAH

entity framework exceptional detail by elmah - ثبت جزئیات استثناهای Entity framework توسط ELMAH

(بیشتر…)

1 the-story-of-unicode
نرم افزار درخواستمزیت های نرم افزارپیاده سازی شده بصورت تحت وب و بدون نیاز به نصب روی سیستم کاربر و یا امکانات خاص جهت اجرای نرم افزار

یکی از مباحثی که به نظرم هر دانشجوی رشته کامپیوتر، فناوری اطلاعات و علاقمند به این حوزه باید بداند بحث کاراکترهاست؛ جدا از اینکه همه ما در مورد وجود ascii یا UTF-8 و … و توضیحات مختصر آن اطلاع داریم ولی عده‌ای از دوستان مثل من هنوز اطلاعات پایه‌ای‌تر و جامع‌تری در این باره نداریم؛ در این مقاله که برداشتی از وب سایت smashing magazine  و W3 است به این مبحث می‌پردازیم.

کامپیوترها تنها با اعداد سر و کار دارند نه با حروف؛ پس این بسیار مهم هست که همه کامپیوترها بر روی یک سری اعداد مشخص به عنوان نماینده‌ای از حروف به توافق برسند. این توافق یکسان بین همه کامپیوترها بسیار مهم هست و باید طبق یک استاندارد مشترک استفاده شود تا در همه سیستم‌ها قابل استفاده و انتقال باشد؛ برای همین در سال ۱۹۶۰ اتحادیه استاندارهای آمریکا، یک سیستم رمزگذاری ۷ بیتی را ایجاد کرد؛ به نام American Standard Code for Information Interchange یا کد استاندارد سازی شده آمریکایی برای تبادل اطلاعات یا همان ASCII. این هفت بیت به ما اجازه می‌داد تا ۱۲۸ حرف را کدگذاری کنیم. این مقدار برای حروف کوچک و بزرگ انگلیسی و هم چنین حروف لاتین، همراه با کدگذاری ارقام و یک سری علائم نگارشی و کاراکترهایی از قبیل space ، tab و موارد مشابه و نهایتا کلیدهای کنترلی کافی بود. در سال ۱۹۶۸ این استاندارد توسط رییس جمهور وقت آمریکا لیندون جانسون به رسمیت شناخته شده و همه سیستم‌های کامپیوتری ملزم به رعایت و استفاده از این استاندارد شدند.
برای لیست کردن و دیدن این کدها و نمادهای حرفیشان می‌توان با یک زبان برنامه نویسی یا اسکریپتی آن‌ها را لیست کرد. کد زیر نمونه‌ای از کد نوشته شده در جاوااسکریپت است.

<html>

<body>
<style type=”text/css”>p {float: left; padding: 0 15px; margin: 0;}</style>

<script type=”text/javascript”>
for (var i=0; i<128; i++) document.writeln ((i%32?”:'<p>’) + i + ‘: ‘ + String.fromCharCode (i) + ‘
‘);

</script>
</body>
</html>

در سال‌های بعدی، با قوی‌تر شدن پردازش‌گرها و ۸ بیت شدن یک بایت به جای ذخیره ۱۲۸ عدد توانستند ۲۵۶ عدد را ذخیره کنند ولی استاندارد اسکی تا ۱۲۸ کد ایجاد شده بود و مابقی را به عنوان ذخیره نگاه داشتند. در ابتدا کامپیوترهای IBM از آن‌ها برای ایجاد نمادهای اضافه‌تر و همچنین اشکال استفاده می‌کرد؛ مثلا کد ۲۰۰ شکل ╚ بود که احتمالا برنامه نویسان زمان داس، این شکل را به خوبی به خاطر میاورند یا مثلا حروف یونانی را اضافه کردند که با کد ۲۲۴ شکل آلفا α بود و بعد‌ها به عنوان code page 437 نامگذاری شد. هر چند که هرگز مانند اسکی به یک استاندارد تبدیل نشد و بسیاری از کشورها از این فضای اضافی برای استانداردسازی حروف خودشان استفاده می‌کردند و در کشورها کدپیج‌های مختلفی ایجاد شد. برای مثال در روسیه کد پیچ ۸۸۵ از کد ۲۲۴ برای نمایش Я بهره می‌برد و در کد پیچ یونانی ۷۳۷ برای نمایش حرف کوچک امگا ω استفاده می‌شد. این کار ادامه داشت تا زمانیکه مایکروسافت در سال ۱۹۸۰ کد پیچ Windows-1251 الفبای سریلیک را ارئه کرد. این تلاش تا سال ۱۹۹۰ ادامه پیدا کرد و تا آن زمان ۱۵ کدپیج مختلف استاندارسازی شده برای الفبایی چون سیریلیک، عربی، عبری و … ایجاد شد که این استانداردها از ISO-8859-1 شروع و تا ISO-8859-16 ادامه داشت و موقعی که فرستنده پیامی را ارسال می‌کرد، گیرنده باید از کدپیج مورد نظر مطلع می‌بود تا بتواند پیام را صحیح بخواند.
بیایید با یک برنامه علائم را در این ۱۵ استاندارد بررسی کنیم. تکه کدی که من در اینجا نوشتم یک لیست را که در آن اعداد یک تا ۱۶ لیست شده است، نشان میدهد که با انتخاب هر کدام، کدها را از ۰ تا ۲۵۵ بر اساس هر استاندارد به ترتیب نمایش می‌دهد. این کار توسط تعیین استاندارد در تگ متا رخ میدهد.
در زمان بارگذاری، استانداردها با کد زیر به لیست اضافه می‌شوند.در مرحله بعد لیستی که postback را در آن فعال کرده‌ایم، کد زیر را اجرا می‌کند. در این کد ابتدا charset انتخاب شده ایجاد شده و سپس یکی یکی کدها را به کاراکتر تبدیل می‌کنیم و رشته نهایی را درج می‌کنیم

private String ISO = “ISO-8859-“;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int i = 1; i < 16; i++)
{
ListItem item = new ListItem();
item.Text = ISO + i.ToString();
item.Value = i.ToString();
DropDownList1.Items.Add(item);
}
ShowCodes(1);
}

}

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropDownList1.SelectedItem != null)
{
int value = int.Parse(DropDownList1.SelectedValue);
ShowCodes(value);
}

}

private void ShowCodes(int value)
{
Response.Charset = ISO + value;
string s = “”;
for (int i = 0; i < 256; i++)
{
char ch = (char)i;
s += i + “-” + ch;
s += “
“;//br tag
}
Label1.Text = s;
}

تقریبا سال ۱۹۹۰ بود که بسیاری از اسناد به همین شیوه‌ها نوشته و ذخیره شد. ولی باز برای بسیاری از زبان‌ها، حتی داشتن یکی دو حرف بیشتر مشکلاتی را به همراه داشت. مثلا حروف بعضی زبان‌ها مثل چینی و ژاپنی چینی که ۲۵۶ عدد، پاسخگو نبود و با آمدن شبکه‌ای چون اینترنت و بحث بین المللی شدن و انتقال اطلاعات، این مشکل بزرگتر از آنچه بود، شد.

یونیکد نجات بخش
اواخر سال ۱۹۸۰ بود که پیشنهاد یک استاندارد جدید داده شد و در آن به هر حرف و یا نماد در هر زبانی یک عدد یکتا نسبت داده میشد و باید بیشتر از ۲۵۶ عدد می‌بود که آن را یونیکد نامیدند. در حال حاضر یونیکد نسخه ۶۰۱ شامل ۱۱۰ هزار کد می شود. ۱۲۸ تای آن همانند اسکی است. از ۱۲۸ تا ۲۵۵ مربوط به علائم و علامت‌هاست که بیشتر آن‌ها از استاندارد ISO-8859-1 وام گرفته شده‌اند. از ۲۵۶ به بعد هم بسیاری از علائم تلفظی و … وجود دارد و از کد ۸۸۰ زبان یونایی آغاز شده و پس از آن زبان‌های سیریلیک، عبری، عربی و الی آخر ادامه می‌یابند. برای نشان دادن یک کد یونیکد به شکل هگزادسیمال U+0048 نوشته می‌شود و برای تبدیل آن به دسیمال ۴*۱۶+۸=۷۲ استفاده می‌شود. به هر کد یونیکد، کد پوینت code point گفته میشود.
در ویکی پدیای فارسی، یونیکد اینگونه توضیح داده شده است: “نقش یونیکد در پردازش متن این است که به جای یک تصویر برای هر نویسه یک کد منحصر به فرد ارایه می‌کند. به عبارت دیگر، یونیکد یک نویسه را به صورت مجازی ارایه می‌کند و کار ساخت تصویر (شامل اندازه، شکل، قلم، یا سبک) نویسه را به عهده نرم‌افزار دیگری مانند مرورگر وب یا واژه‌پرداز می‌گذارد. “
یونیکد از ۸ بیت یا ۱۶ بیت استفاده نمی‌کند و با توجه به اینکه دقیقا ۱۱۰ ،۱۱۶ کد را حمایت می‌کند به ۲۱ بیت نیاز دارد. هر چند که کامپیوترها امروزه از معمار‌های ۳۲ بیتی و ۶۴ بیتی استفاده می‌کنند، این سوال پیش می‌آید که ما چرا نمی‌توانیم کاراکترها را بر اساس این ۳۲ بیت و ۶۴ بیت قرار بدهیم؟ پاسخ این سوال این‌است که چنین کاری امکان پذیر است و بسیاری از نرم افزارهای نوشته شده در زبان سی و سی ++ از wide character حمایت می‌کنند. این مورد یک کاراکتر ۳۲ بیتی به نام wchar_t است که نوعی داده char توسعه یافته هشت بیتی است و بسیاری از مرورگرهای امروزی از آن بهره مند هستند و تا ۴ بیلیون کاراکتر را حمایت می‌کنند.
شکل زیر دسته بندی از انواع زبان‌های تحت حمایت خود را در نسخه ۵.۱ یونیکد نشان می‌دهد

 

کد زیر در جاوااسکریپت کاراکترهای یونیکد را در مرز معینی که برایش مشخص کرده‌ایم نشان می‌دهد

<html>

<body>
<style type=”text/css”>p {float: left; padding: 0 15px; margin: 0;}</style>

<script type=”text/javascript”>
for (var i=0; i<2096; i++)
document.writeln ((i%256?”:'<p>’) + i + ‘: ‘ + String.fromCharCode (i) + ‘
‘);

</script>
</body>
</html>

CSS & Unicode
یکی از جذاب‌ترین خصوصیات در css، خصوصیت Unicode-range است. شما میتوانید برای هر کاراکتر یا حتی رنج خاصی از کاراکترها، فونت خاصی را اعمال کنید. به دو نمونه زیر دقت کنید:

/* cyrillic */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}

در صورتی که در Unicode-range، تنها یک کد مانند U+20AD نوشته شود، فونت مورد نظر فقط بر روی کاراکتری با همین کد اعمال می‌شود. ولی اگر بین دو کد از علامت – استفاده شود، فونت مورد نظر بر روی کاراکترهایی که بین این رنج هستند اعمال می‌شود U+0025-00FF و حتی می‌توان اینگونه نوشت ??U+4 روی کاراکترهایی در رنج U+400 تا U+4FF اعمال می‌شوند. برای اطلاعات بیش‌تر به اینجا و اینجا مراجعه کنید.
به ۶۵۵۳۶ کد اول یونیکد Basic Multilingual Plan یا به اختصار BMP می‌گویند و شامل همه کاراکترهای رایجی است که مورد استفاده قرار می‌گیرند. همچنین یونیکد شامل یک فضای بسیار بزرگ خالی است که به شما اجازه توسعه دادن آن را تا میلیون‌ها کد می‌دهد. به کاراکترهایی که در این موقعیت قرار می‌گیرند supplementary characters یا کاراکترهای مکمل گویند. برای اطلاعات بیشتر می‌توانید به سایت رسمی یونیکد مراجعه کنید. در اینجا هم مباحث آموزشی خوبی برای یونیکد دارد، هر چند کامل‌تر آن در سایت رسمی برای نسخه‌های مختلف یونیکد وجود دارد.

 the story of unicode 2 - داستانی از Unicode

UTF-8 نجات بخش می‌شود
بسیاری از مشکلات ما حل شد. همه حروف را داریم و مرورگر‌ها نیز همه حروف را میشناسند؛ ولی برای ما دو مشکل ایجاد کرده است:
بسیاری از نرم افزارها و پروتکل‌ها هنوز ۸ بیتی کار می‌کنند.
اگر یک متن انگلیسی ارسال کنید، ۸ بیت هم کافی است ولی در این حالت ۳۲ بیت جابجا می‌شود؛ یعنی ۴ برابر و در ارسال و دریافت و پهنای باند برایمان مشکل ایجاد می‌کند.
برای حل این مشکل استاندارهای زیادی چون USC-2 یا UTF-16 ایجاد شدند ولی در سال‌های اخیر برنده رقابت، UTF-8 بود که مخفف عبارت Universal Character Set Transformation Format 8 bit می‌باشد. این کدگذاری بسیار هوشمندانه عمل می‌کند. موقعی که شما کاراکتری را وارد می‌کنید که کدش بین ۰ تا ۲۵۵ است، ۸ بیت به آن اختصاص می‌دهد و اگر در محدوده‌ای است که بتوان دو بایت را به آن اختصاص داد، دوبایت و اگر بیشتر بود، سه بایت و اگر باز بیشتر بود ۴ بایت به آن اختصاص میدهد. پس با توجه به محدوده کد، تعداد بایت‌ها مشخص می‌شوند. بنابراین یک متن نوشته شده انگلیسی که مثلا از کدهای بین ۰تا ۱۲۸ استفاده می‌کند و فرمت ذخیره آن UTF-8 باشد به ازای هر کارکتر یک بایت ذخیره می‌کند.

 the story of unicode 3 - داستانی از Unicode

مقایسه‌ای بین نسخه‌های مختلف :

 the story of unicode 4 - داستانی از Unicode

همانطور که می‌بینید UTF-8 برای کاراکترهای اسکی، از یک بایت و برای دیگر حروف از دوبایت و برای بقیه BMP‌ها از سه بایت استفاده میکند و در صورتی که کاراکتری در ناحیه مکمل supplementary باشد، از چهار بایت استفاده خواهد کرد. UTF-16 از دو بایت برای نمایش کاراکترهای BMP و از ۴ بایت برای نمایش کاراکترهای مکمل استفاده می‌کند و در UTF-32 از ۴ بایت برای همه کاراکترها یا کد پوینت‌ها استفاده می‌شود.

(بیشتر…)

automatic-template-for-preparing-packages-nyvgt
نرم افزار درخواستمزیت های نرم افزارپیاده سازی شده بصورت تحت وب و بدون نیاز به نصب روی سیستم کاربر و یا امکانات خاص جهت اجرای نرم افزار

 

روش‌های زیادی برای تهیه‌ی یک بسته‌ی نیوگت وجود دارند، مانند استفاده از برنامه‌ی NuGet Package Explorer و یا تهیه‌ی یک فایل nuspec و تغییر مداوم جزئیات آن، به ازای هر نگارش جدید پروژه. در ادامه قصد داریم روش خودکار سازی این تغییرات را بررسی کنیم.

الف) تهیه فایل nuspec
NuGet قابلیت پذیرش متغیرهای خود تکمیل شونده‌ای را نیز دارد. فایل nuspec یا جزئیات بسته‌ی تولیدی نیوگت، در این حالت یک چنین شکلی را پیدا می‌کند:

<?xml version=”1.0″?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<licenseUrl>https://site.com/prj/LICENSE</licenseUrl>
<projectUrl>https://site.com/prj</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<copyright>Copyright 2015 My Name</copyright>
</metadata>
</package>

برای مثال اگر پروژه‌ی ما TestNuget نام دارد، فایلی به نام TestNuget.nuspec را با محتویات فوق برای آن تهیه خواهیم کرد. همانطور که مشاهده می‌کنید، در این فایل ویژه، هیچکدام از اطلاعات شماره نگارش پروژه، نام نویسنده و غیره، از پیش تعیین نشده‌اند. این اطلاعات، از فایل AssemblyInfo.cs پروژه، به صورت خودکار دریافت خواهند شد و نکته‌ی مهم آن، قرار گرفتن این فایل nuspec در پوشه‌ی اصلی پروژه است. از این جهت که برای کامپایل آن و تبدیل به یک بسته‌ی نیوگت، فایل nuget.exe را بر روی فایل پروژه‌ی اصلی برنامه اجرا خواهیم کرد و نه بر روی این فایل nuspec.
بنابراین تکمیل اطلاعات فایل AssemblyInfo.cs را فراموش نکنید. برای مثال اطلاعات AssemblyCompany آن، در قسمت authors فایل فوق جایگزین می‌شود.

 

ب) تهیه فایل NuGet.exe
فایل NuGet.exe را جهت کامپایل فایل فرضی TestNuget.nuspec نیاز داریم. می‌توان آن‌را از سایت کدپلکس تهیه کرد و یا تنها کافی است بر روی Solution موجود در VS.NET کلیک راست کرده و گزینه‌ی Enable NuGet Package Restrore را انتخاب کنیم. با اینکار به صورت خودکار پوشه‌ی ویژه‌ای به نام .nuget به همراه فایل NuGet.exe ایجاد می‌شود.

ج) کامپایل فایل nuspec
در همان پوشه‌ی جدید .nuget، یک فایل bat را با محتوای ذیل تهیه کنید:

“%~dp0NuGet.exe” pack “..\TestNuGet\TestNuGet.csproj” -Prop Configuration=Release
copy “%~dp0*.nupkg” “%localappdata%\NuGet\Cache”
pause

در این مثال، مسیر TestNuGet\TestNuGet.csproj به محل قرارگیری فایل پروژه‌ی برنامه اشاره می‌کند. در اینجا فایل nuget.exe را بر روی فایل csproj برنامه اجرا خواهیم کرد. با توجه به اینکه قرار است یک بسته‌ی عمومی منتشر شود، بهتر است تنظیمات تولید بسته‌ی نیوگت را بر روی حالت release قرار داد که در این دستور، قید شده‌است.
در ادامه برای اینکه امکان آزمایش محلی این بسته را نیز داشته باشیم، فایل بسته‌ی تولیدی، به کش محلی نیوگت، در سیستم جاری کپی می‌شود.

نکته‌ی جالب این روش، تهیه‌ی قسمت dependencies پروژه، به صورت خودکار است:

<?xml version=”1.0″?>
<package xmlns=”http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd”>
<metadata>
<id>TestNuget</id>
<version>1.0.0.0</version>
<title>TestNuget</title>
<authors>Vahid N.</authors>
<owners>Vahid N.</owners>
<licenseUrl>https://site.com/prj/LICENSE</licenseUrl>
<projectUrl>https://site.com/prj</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>This is a test.</description>
<copyright>Copyright 2015 My Name</copyright>
<dependencies>
<dependency id=”EntityFramework” version=”6.1.2″ />
</dependencies>
</metadata>
</package>

 اطلاعاتی را که در اینجا مشاهده می‌کنید، حاصل کامپایل فایل nuspec معرفی شده‌ی در ابتدای بحث است (با اجرای فایل bat تهیه شده) که یک کپی از آن در فایل TestNuget.1.0.0.0.nupkg نهایی نیز قرار می‌گیرد. به این ترتیب دیگر نیازی نیست تا این قسمت را به صورت دستی معرفی و هر بار با به روز رسانی وابستگی‌های پروژه، شماره نگارش‌های آن‌ها را نیز به روز کرد. اطلاعات version به صورت خودکار از پروژه‌ی جاری استخراج می‌شوند.

د) آزمایش محلی بسته‌ی جدید
اکنون که فایل TestNuget.1.0.0.0.nupkg تولیدی را در آدرس localappdata%\NuGet\Cache% نیز کپی کرده‌ایم، به منوی Tools/Options مراجعه و در قسمت NuGet Package Manager آن، به قسمت Package sources، این آدرس کش محلی را نیز معرفی کنید:

automatic template for preparing packages nyvgt - قالبی خودکار برای تهیه‌ی بسته‌های نیوگت

به این ترتیب، بدون ارسال یک بسته به سایت اصلی نیوگت، می‌توان بسته را از کش محلی نیوگت نصب و آزمایش کرد:

automatic template for preparing packages nyvgt 2 - قالبی خودکار برای تهیه‌ی بسته‌های نیوگت

(بیشتر…)

obtain-ip-in-sql-server 3
نرم افزار درخواستمزیت های نرم افزارپیاده سازی شده بصورت تحت وب و بدون نیاز به نصب روی سیستم کاربر و یا امکانات خاص جهت اجرای نرم افزار
 
همانطور که از نامش پیداست jcookie یک پلاگین jquery است. این پلاگین به شما این اجازه را می‌دهد تا هر نوع داده ای را که مایل هستید از قبیل رشته‌ها، آرایه‌ها و object را در قالب json با رمزگذاری base 64 ذخیره نمایید. استفاده از این رمزگذاری باعث کوچکتر شدن حجم کوکی تا ۷۰ درصد می‌شود.
 
ذخیره کوکی
برای ساخت یک کوکی به روش زیر اقدام می‌کنیم. استفاده از jCookies.$ دو خاصیت به نام‌های نام کوکی و مقدار کوکی را name & Value در دسترس ما می‌گذارد:

var d = new Date();

                           $.jCookies({
                                name: ‘dotnettips.info’,
                                value: { Title: ‘ساخت کوکی با jcookie’, Author: ‘علی یگانه مقدم’, Seen: d.getDate(), Favorite: true }
                            });

همانطور که می‌بینید ذخیره اطلاعات توسط jcookie بسیار ساده و راحت بوده و هر نوع داده ای در آن به راحتی قابل ذخیره سازیست. برای مثال می‌توانید اطلاعات یک کلاس را خیلی راحت و سریع با آن ذخیره کنید. به طور پیش فرض تاریخ انقضای کوکی ۲۷ روز بعد از ایجاد آن می‌باشد. در صورتی که تمایل دارید این تاریخ را تغییر دهید یکی از خاصیت‌های seconds,minutes,hours و days در دسترس شماست و مقادیری که جلوی آن‌ها به کارگرفته می‌شود باید نوع صحیح بوده و در صورتی که مقدار نامعتبر وارد شود خاصیت مورد نظر نادیده گرفته می‌شود.

$.jCookies ({ name : ‘User’, value : { username : ‘Bob’ , level : 5 }, minutes : 60 });

برای تغییر پیش فرض‌های ساخت کوکی مانند انقضای ۲۷ روز به عدد پیش فرض خودتان فایل jcookies.js را باز کرده و تنظیمات پیش فرض آن را تغییر بدهید. برای تغییر دنبال کد زیر بگردید:

 

$.jCookies.defaults =
{
name : ”,
value : ”,
days : 27
}

بازیابی کوکی
برای بازیابی کوکی مجددا از jCookies.$ استفاده می‌شود ولی تنها باید یک خاصیت get که نام کوکی هست را بنویسید:
var values = $.jCookies ({ get: ‘dotnettips.info’ });
 
در صورتی که نام کوکی‌ای که درخواست کرده اید وجود نداشته باشد یا اینکه تاریخ انقضای آن سر رسیده است و از سیستم کلاینت حذف شده است یا اینکه هنگام درخواست کوکی با خطایی مواجه شده باشد، مقدا برگشتی false خواهد بود و اگر نیاز دارید که بدانید آیا نوع برگشتی false به خاطر خطا بوده است یا خیر یک خاصیت نوع بول به نام error هم اضافه می‌شود:
 
var values = $.jCookies({ get: ‘Rutabaga’, error: true });
 
در صورتی که خطایی داده شود response مقدار values در مرورگر کروم به شکل زیر خواهد بود. در هر مرورگر نحوه نمایش خطا می‌تواند متفاوت باشد.
 

Error : {
arguments : undefined,
message : “Invalid base64 data”,
stack : “—”,
type : undefined
}

بازیابی همه کوکی ها

در صورتی که به خاصیت get مقدار * را بدهید تمامی کوکی‌ها برگشت داده خواهند شد و به صورت آرایه ای از نام کوکی‌ها در دسترسی خواهند بود:
 

var values = $.jCookies({ get: ‘*’ });
alert(values[“dotnettips.info”].Title);
alert(values[“data2”].Title);

 

حذف کوکی
نحوه کدنویسی حذف کوکی هم دقیقا مشابه خواندن کوکی است؛ با این تفاوت که به جای استفاده از خاصیت get از خاصیت erase استفاده می‌کنیم و با دادن نام کوکی به این خاصیت، کوکی حذف خواهد شد:
 
var value = $.jCookies({ erase: ‘dotnettips.info’ });
 
در صورتی که کوکی وجود داشته باشد، آن را حذف کرده و مقدار true را برگشت خواهد زد و در صورتی که کوکی وجود نداشته باشد مقدار false را بر میگرداند.
 
بازیابی کوکی در سمت سرور با سی شارپ
در این روش ما ابتدا با همان دستور معمولی دات نت یعنی page.request.cookie درخواست دریافت کوکی را می‌دهیم ولی از آنجا که در jcookie دو عمل روی داده‌ها صورت گرفته است باید دو کار اضافه‌تر را انجام داد:
  1. برگشت داده‌ها از حالت رمزگذاری base64
  2. داده‌ها در فرمت json هستند و باید به حالتی قابل استفاده در محیط شی گرا تبدیل شوند.
برای بازگردانی از حالت base64 از کلاس و متد Convert.FromBase64String در فضای نام system.convert استفاده می‌کنیم که آرایه ای از نوع بایت را بر میگرداند و از Encoding.UTF8.GetString هم برای decode کردن آرایه به نوع رشته استفاده می‌کنیم. تا به اینجای کار داده‌های ما به صورت یک json خوانا با فرمت string درآمده است. برای دسترسی به داده‌های موجود در این فرمت باید آن‌ها را Deserialize کنیم که این کار را از طریق کلاس JavaScriptSerializer  در فضای نام System.Web.Script.Serialization انجام می‌دهیم و از کلاس دیکشنری برای ذخیره داده‌های برگشتی استفاده می‌کنیم که نوع string برای نام خاصیت و نوع آبجکت برای ذخیره مقدار خاصیت خواهد بود.  یعنی برای بازگردانی اولین مثال بالا باید داده‌های در نوع دیکشنری به صورت زیر لیست شوند
  
 Title ایجاد کوکی با jcookie 
 Author  علی یگانه مقدم
 Seen  2015/1/14
 Favorite  true

byte[] from64 = Convert.FromBase64String(Page.Request.Cookies[“dotnettips.info”].Value);
string json = Encoding.UTF8.GetString(from64);
Dictionary<string, object> article =new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Page.Response.Write(“Title: “+ (string)article[“Title”]);

 

پشتیبانی از یونیکد
موقعی که من اولین مثال بالا را نوشتم و مقادیر را به صورت فارسی وارد کردم متوجه شدم که رشته‌های یونیکد را انکود نمی‌کند و در نتیجه زبان فارسی در آن پشتیبانی نمی‌شود. برای همین تغییراتی در فایل js ایجاد کرده و عبارت value قبل از تبدیل به base64 را به صورت utf-16 انکود کردم و در هنگام خواندن کوکی هم به صورت utf-16 دیکود کردم و مشکل زبان فارسی هم در این حالت حل شد. البته کدی که اضافه کردم قابلیت‌های انکودینگ بیشتری هم دارد.
فقط تنها مورد این هست که برای خواندن کوکی در سمت سرور باید یک تغییر کوچک یک کلمه ای بدهیم؛ باید کلمه UTF8 را به Unicode که می‌شود همان UTF-16 در کد تغییر دهیم، که به کد زیر تغییر خواهد یافت:

byte[] from64 = Convert.FromBase64String(Page.Request.Cookies[“dotnettips.info”].Value);
            string json = Encoding.Unicode.GetString(from64);
            Dictionary<string, object> article =new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
            Page.Response.Write(“Title: “+ (string)article[“Title”]);

(بیشتر…)

obtain-ip-in-sql-server
نرم افزار درخواستمزیت های نرم افزارپیاده سازی شده بصورت تحت وب و بدون نیاز به نصب روی سیستم کاربر و یا امکانات خاص جهت اجرای نرم افزار

توسط روشی که امروز باهم بررسی می کنیم شما می توانید IP کاربری که به سرور متصل شده را بدست آورید.

بدست آوردن IP کاربر کاربردهای فراوانی دارد . شما می توانید اجازه دسترسی به دیتاهای خاصی را به کاربر بدهید یا کلا ورود کاربر را مسدود کنید یا حتی می توانید ساعات ورود و خروج کاربران را ثبت کنید تا برای گزارشات خاصی استفاده شود . 

CREATE FUNCTION [dbo].[GetCurrentIP] ()
RETURNS varchar(255)
AS
BEGIN
DECLARE @IP_Address varchar(255);
SELECT @IP_Address = client_net_address
FROM sys.dm_exec_connections
WHERE Session_id = @@SPID;
Return @IP_Address;
END

 

جدول sys.dm_exec_connections از جداول SQL SERVER حاوی اطلاعاتی در مورد اتصال به Instance های نصب شده و جزییات هر یک از این اتصال ها می باشد بطور مثال مدت زمان برقراری اتصال ((connect_time ، پروتکل برقراری اتصال ( protocol_type که می تواند TDS یا SOAP باشد) ، protocol_version ، last_write ، last_read ( مدت زمان نوشته شدن و خوانده شدن اطلاعات ) و …

 

فیلد client_net_address هم آدرس هاست (ip) اتصال شده به سرور را برمی گرداند .

 

فیلد Session_id هم id سشن (session) مربوط به اتصال کنونی است .

 

(بیشتر…)