۱۳۸۸/۱۱/۰۴

آشنايي با DGML


يكي از قابليت‌هاي جديد VS2010 ، معرفي يك markup language است به نام DGML كه از آن جهت data visualization و رسم انواع و اقسام گراف‌ها استفاده مي‌شود.




چند دموي جالب از آن در اين سايت قابل دريافت است (اگر موفق به باز كردن سايت شديد كه چقدر هم خوب، اگر نه، mirror اين دموها از آدرس‌هاي زير هم قابل دريافت است):




۱۳۸۸/۱۱/۰۱

سرورهاي متصل شده‌ي SQL Server و مبحث تراكنش‌ها


يكي از قابليت‌هاي جالب SQL Server در يك شبكه محلي امكان link و اتصال آن‌ها به يكديگر است. به اين صورت امكان كوئري گرفتن (و يا اعمال متداول SQL ايي) از دو يا چند سرور مختلف با دستورات T-SQL ميسر مي‌شود؛ به نحوي كه حس يكپارچگي ديتابيس‌هاي اين سرورها را حين كوئري نوشتن خواهيم داشت.
براي مثال فرض كنيد دو سرور SQL1 و SQL2 را در شبكه داريم. مي‌خواهيم در سرور SQL1 اتصالي را به سرور SQL2 ايجاد كنيم.

USE master

EXEC sp_addlinkedserver
'SQL2',
N'SQL Server'

sp_addlinkedsrvlogin @useself='false ', @rmtsrvname = 'SQL2',
@rmtuser = 'sa',
@rmtpassword = 'pass#'

دستورات T-SQL فوق كار ثبت يك liked server جديد و اعمال مشخصات كاربري كه توسط آن قرار است به سرور SQL2 دسترسي داشت، انجام مي‌دهند.
اكنون جهت بررسي اين اتصال در سرور SQL1 كوئري زير را اجرا مي‌كنيم:

select * from sql2.faxManager.dbo.tblErja

كه نحوه‌ي فراخواني جدول مورد نظر بايد به صورت Server.DatabaseName.dbo.TableName در آن رعايت شود.
تا اينجا همه چيز خوب است. مشكل از زماني شروع مي‌شود كه بخواهيم تراكنش‌ها را نيز دخالت دهيم و اصولي كار كنيم. براي مثال:

begin distributed tran
select * from sql2.faxManager.dbo.tblErja
commit tran

خطايي كه در ويندوز سرور 2003 با آخرين به روز رساني‌ها ظاهر مي‌شود به صورت زير است:

The operation could not be performed because OLE DB provider for linked server was unable to begin a distributed transaction.
OLE DB provider for linked server returned message "The partner transaction manager has disabled its support for remote/network transactions.".


به صورت پيش فرض اين نوع تراكنش‌هاي توزيع شده غيرفعال هستند مگر اينكه فعال شوند و روش حل مشكل نيز به صورت زير مي‌باشد:
قبل از هر كاري به كنسول سرويس‌هاي ويندوز مراجعه كرده و از در حال اجرا بودن سرويس Distribute Transaction Coordinator اطمينان حاصل كنيد.
سپس به قسمت زير مراجعه نمائيد:
Control Panel > Administrative Tools > Component Services


نود مربوط به Component Service را گشوده و سپس بر روي My Computer كليك راست كرده و گزينه‌ي خواص را انتخاب كنيد.
در صفحه‌ي بازه شده به برگه‌ي MSTDC مراجعه كرده و بر روي دكمه‌ي Security Configuration كليك نمائيد.
اكنون تنظيمات آن‌را مطابق شكل زير تغيير دهيد.


اين تنظيم بايد بر روي هر دو سرور SQL1 و SQL2 انجام شود.

پس از اين تغييرات كه شامل راه اندازي مجدد سرويس Distribute Transaction Coordinator نيز خواهد شد، مشكل خطاي فوق برطرف شده و امكان استفاده از تراكنش‌ها در linked servers نيز ميسر مي‌شود.

مشكل ديگري كه به آن برخوردم خطاي زير است:

Unable to start a nested transaction for OLE DB provider for linked server . A nested transaction was required because the XACT_ABORT option was set to OFF.
OLE DB provider for linked server returned message "Cannot start more transactions on this session.".


براي حل اين مشكل يك سطر زير را بايد به ابتداي كوئري خود اضافه كرد كه جزو الزامات تراكنش‌هاي توزيع شده است و به اين صورت از rollback كامل تمامي دستورات موجود فراخواني شده T-SQL در صورت بروز كوچكترين خطايي اطمينان حاصل مي‌كند:
SET XACT_ABORT ON


براي مطالعه بيشتر:
MSDTC Troubleshooting

۱۳۸۸/۱۰/۲۹

چرا در سازمان‌ها برنامه‌هاي وب جايگزين برنامه‌هاي دسكتاپ شده‌اند (يا مي‌شوند)؟


- برنامه‌هاي وب نيازي به نصب بر روي تك تك كلاينت‌ها و همچنين به روز رساني مداوم كلاينت‌ها را ندارند. به اين صورت مديريت چند صد كاربر در يك سازمان ساده‌تر از قبل خواهد بود. ديگر نگران اين نخواهيد بود كه آيا فلان كاربر آخرين به روز رساني‌ها را نصب كرده (دريافت كرده) يا خير.
- امكان دسترسي از راه دور، براي مثال از طريق اينترنت يا VPN يا RRAS و خطوط دايال آپ (براي مثال دسترسي ساده‌تر دفاتر مختلف يك سازمان به اطلاعات يكديگر يا امكان داشتن كاركناني كه از راه دور براي شما كار مي‌كنند).
- امكان ذخيره سازي داده‌ها در سازماني ديگر (هاست كردن اين برنامه‌ها در محيط‌هاي ابري(!) (cloud computing) هزينه‌هاي تهيه و نگهداري سخت افزارهاي يك سازمان را نيز كاهش مي‌دهند).
- كاهش هزينه‌هاي سازمان با توجه به اينكه اگر از سرورهاي قدرتمندي استفاده شود؛ از يك برنامه‌ي وب چندين هزار يا چند ميليون كاربر مي‌توانند استفاده كنند بدون اينكه نگران تامين هزينه مجوز استفاده از برنامه‌ي تهيه شده به ازاي هر كاربر باشيد.
- امكان دسترسي به برنامه‌ي وب تهيه شده در انواع و اقسام سيستم عامل‌هايي كه تنها مجهز به يك مرورگر وب هستند (نتيجه نهايي قابل استفاده مستقل از سكو است). براي مثال اين‌ روزها به كمك Adobe AIR ، Silverlight و يا كتابخانه‌هاي اسكريپتي مانند jQuery و ASP.Net Ajax، بسياري از توانايي‌هاي نمايشي برنامه‌هاي دسكتاپ را در وب نيز مي‌توان شاهد بود با اين خصوصيت كه نتيجه‌ي نهايي مستقل از سكو است.
- در اين حالت كلاينت‌ها نيازي به داشتن سخت افزارهاي قوي ندارند (كه در كاهش هزينه‌هاي يك سازمان مؤثر است). همچنين اين برنامه‌ها مشكلات ناسازگاري با سخت افزارها و نگارش‌هاي مختلف سيستم عامل‌ها را نيز ندارند. بنابراين يك سازمان مي‌تواند بودجه‌ي خود را صرف تهيه‌ي سرورهاي بهتري كند.
- كلاينت‌ها با توجه به محدود بودن دسترسي‌هاي امنيتي اعمالي توسط مرورگرها، امنيت بيشتري خواهند داشت. به همين ترتيب كاربران براي استفاده از اين برنامه‌ها نيز نيازي به دسترسي بالا در يك سازمان براي اجراي مرورگر خود نخواهند داشت (كمتر جمله‌ي "من دسترسي ادمين مي‌خواهم" را خواهيد شنيد).
- امكان مونيتور كردن ساده‌تر فعاليت كاربران در برنامه.
- در صورت محافظت از سرور، كدهاي شما از خطر دزديده شدن مصون‌(تر) هستند.
- مديريت ساده‌تر و مجتمع اطلاعات توليدي با توجه به اينكه همه چيز بايد بر روي سرور ذخيره شود. به اين صورت مديريت نقل مكان كاربران از يك كامپيوتر به كامپيوتري ديگر نيز ساده‌تر مي شود؛ زيرا چيزي را قرار نيست جابجا كنند (نه اطلاعات و نه برنامه ‌را). اگر يكي از كامپيوترهاي كلاينت‌ها قابل استفاده نباشد، به سادگي مي‌تواند از كامپيوتري ديگر در شبكه استفاده كند، بدون اينكه معطل تيم فني شود تا برنامه‌اي را براي او نصب و راه اندازي كنند. به علاوه تهيه پشتيبان از اطلاعات سرورها نيز هميشه ساده‌تر است از تهيه پشتيبان از 100 ها كامپيوتر موجود در شبكه.
- اگر خروجي برنامه‌ي وب شما تنها از صفحات وب و جاوا اسكريپت تشكيل شده باشد، امكان دسترسي آن در دستگاه‌هاي موبايل به سادگي ميسر است.

۱۳۸۸/۱۰/۲۷

تهيه گزارش از منسوخ شده‌هاي مورد استفاده در SQL Server 2008


مطلب "منسوخ شده‌ها در نگارش‌هاي جديد SQL server" را احتمالا به خاطر داريد. جهت تكميل آن، كوئري زير را هم مي‌توان ذكر كرد:

SELECT instance_name,
cntr_value
FROM sys.dm_os_performance_counters
WHERE OBJECT_NAME = 'SQLServer:Deprecated Features'
AND cntr_value > 0
ORDER BY
cntr_value DESC

توسط اين كوئري گزارشي از منسوخ شده‌هاي مورد استفاده‌ در ديتابيس‌هاي شما ارائه مي‌شود. براي مثال چندبار از text و ntext استفاده كرده‌ايد، آيا هنوز compatibility level ديتابيس‌هاي خود را تغيير نداده‌ايد و مثال‌هايي از اين دست.

براي مثال جهت يافتن سريع فيلدهاي منسوخ شده text و image ديتابيس جاري از كوئري زير مي‌توان كمك گرفت:
SELECT O.Name,
col.name AS ColName,
systypes.name
FROM syscolumns col
INNER JOIN sysobjects O
ON col.id = O.id
INNER JOIN systypes
ON col.xtype = systypes.xtype
WHERE O.Type = 'U'
AND OBJECTPROPERTY(o.ID, N'IsMSShipped') = 0
AND systypes.name IN ('text', 'ntext', 'image')
ORDER BY
O.Name,
Col.Name

۱۳۸۸/۱۰/۲۵

ليست دوره‌هاي آموزشي سايت MS-DEV


سايت MS-DEV متشكل است از يك سري دوره آموزشي مباحث مختلف مانند XAML ، سيلورلايت، WPF ، SQL Server 2008 ، windows server 2008 و غيره.
ليست كامل اين دوره‌ها به همراه آدرس‌هاي ويديوهاي رايگان مرتبط را از آدرس زير مي‌توانيد دريافت كنيد:




۱۳۸۸/۱۰/۲۳

سخت افزارهاي قديمي و ويندوز 7


يك مودم d-link قديمي external دارم (DFM-560E) كه آخرين درايور آن مربوط به ويندوز XP، آن هم 32 بيتي است.
با نصب ويندوز 7 64 بيتي اين مودم به صورت يك analog modem غيرقابل استفاده در device manager شناسايي شد. هر چند ويندوز 7 توانايي يافتن آخرين درايورهاي مرتبط را از اينترنت و سايت مايكروسافت دارد اما چون مطابق جستجويي كه انجام دادم اين نوع مودم d-link صرفا براي خارج از آمريكا تهيه و توليد شده، ديگر درايوري براي آن تهيه نخواهد شد. خوب، خدا را شكر!
اين مودم، مستعمل ماند تا اينكه در يكي از سايت‌ها، مقاله‌ي زير را ديدم:


اين مقاله در مورد همان گزينه‌ي add new hardware ويندوزهاي قبلي كه در اينجا به نام add legacy hardware تغيير نام يافته، صحبت مي‌كند.
در device manager ويندوز 7 از منوي Actions گزينه‌ي add legacy hardware را انتخاب كنيد تا همان ويزاد آشناي add new hardware ويندوز XP ظاهر شود. تمام مراحل آن هم مانند قبل است.
در مرحله‌ي have disk مربوط به مودم، فايل زير را كه مربوط به معرفي درايور مودم ويندوز 64 بيتي است به آن معرفي كردم و مشكل حل شد (احتمالا با تمام مودم‌هايي با chipset از نوع Conexant بايد كار كند).
دريافت فايل




الان هنوز همان analog modem شناسايي نشده باقي است اما مودم فوق نيز شناسايي شد و بدون مشكل كار مي‌كند.



هنگام ساخت كانكشن دايال آپ هم اين مودم جديد شناسايي شده و قابل استفاده است.




۱۳۸۸/۱۰/۲۱

كش كردن اطلاعات غير پويا در ASP.Net - قسمت چهارم


قسمت‌هاي اول تا سوم اين مقاله: + و + و +

در قسمت چهارم قصد داريم هدر مربوط به Content Expiration Date را توسط يك Http module به محتواي غيرپوياي سايت مانند تصاوير ، فايل‌هاي CSS و غيره اعمال كنيم. اين روش از روش قسمت دوم ساده‌تر است و جامع‌تر.
ابتدا يك پروژه‌ي Class library جديد را به نام StaticContentCacheModule ايجاد كرده و سپس ارجاعي را به اسمبلي استاندارد System.Web.dll به آن خواهيم افزود. سپس كدهاي مرتبط با اين ماژول به شرح زير هستند:

//StaticCache .cs
using System;
using System.Web;

namespace StaticContentCacheModule
{
public class StaticCache : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += context_PreSendRequestHeaders;
}

static void context_PreSendRequestHeaders(object sender, EventArgs e)
{
//capture the current Response
var currentResponse = ((HttpApplication)sender).Response;

if (CacheManager.ShouldCache(currentResponse.ContentType))
{
currentResponse.AddHeader("cache-control", "public");
currentResponse.AddHeader("Expires", DateTime.Now.Add(TimeSpan.FromDays(30)).ToString());
}
}

public void Dispose() { }
}
}

در اينجا ContentType تك تك عناصري كه توسط وب سرور ارائه خواهند شد، بررسي مي‌شود. اگر نيازي به كش شدن آن‌ها وجود داشت (توسط كلاس CacheManager اين امر مشخص مي‌گردد)، هدر مربوطه اضافه مي‌گردد.

//CacheManager.cs
using System;

namespace StaticContentCacheModule
{
class CacheManager
{
public static bool ShouldCache(string contentType)
{
contentType = contentType.ToLower();
string[] parts =
contentType.Split(
new[] { ';' },
StringSplitOptions.RemoveEmptyEntries
);

if (parts.Length > 0)
contentType = parts[0];

bool cache = false;

switch (contentType)
{
case "text/css":
cache = true; break;
case "text/javascript":
case "text/jscript":
cache = true; break;
case "image/jpeg":
cache = true; break;
case "image/gif":
cache = true; break;
case "application/octet-stream":
cache = true; break;
default:
{
if (contentType.Contains("javascript"))
cache = true;
if (contentType.Contains("css"))
cache = true;
if (contentType.Contains("image"))
cache = true;
if (contentType.Contains("application"))
cache = true;
}
break;
}

return cache;
}
}
}

در اين كلاس، contentType دريافتي بررسي مي‌شود. اگر نوع محتواي قابل ارائه از نوع CSS ، JavaScript ، تصوير و يا Application بود، يك مقدار true بازگشت داده خواهد شد.
نهايتا براي استفاده از اين Http module جديد در IIS6 به قبل در وب كانفيگ برنامه خواهيم داشت:

<httpModules>
<add name="StaticContentCacheModule" type="StaticContentCacheModule.StaticCache, StaticContentCacheModule"/>
</httpModules>

و يا در IIS7 اين تغييرات به صورت زير مي‌تواند باشد:

<system.webServer>
<modules>
<add name="StaticContentCacheModule" type="StaticContentCacheModule.StaticCache, StaticContentCacheModule"/>
</modules>

اكنون اگر يك پروژه‌ي آزمايشي جديد ASP.Net را گشوده و فايل css ساده‌اي را به آن اضافه كنيم، بررسي هدر نهايي توسط افزونه‌ي YSlow به صورت زير خواهد بود:



۱۳۸۸/۱۰/۱۹

حذف هدرهاي مربوط به وب سرور از يك برنامه‌ي ASP.Net


به همراه هر درخواستي از سرور چه از طرف كلاينت و چه از طرف سرور، يك سري header نيز ارسال مي‌شود. براي مثال مرورگر، نوع خود را به همراه يك سري از قابليت‌هاي مربوطه مانند الگوريتم‌هاي فشرده سازي پشتيباني شده به سرور ارسال مي‌كند و در مقابل وب سرور هم يك سري هدر را مانند مدت زمان كش كردن اطلاعات دريافتي، نوع و نگارش سرور و امثال آن، به كلاينت ارسال خواهد كرد.
از ديدگاه امنيتي اين اطلاعات اضافي هستند. براي مثال از تصوير زير (كه با استفاده از افزونه‌ي فايرباگ تهيه شده) دقيقا مي‌توان وب سرور، نگارش آن و بسياري از موارد ديگر را به سادگي تشخيص داد. در ادامه مي‌خواهيم اين هدرهاي اضافي را حذف كنيم.



امكان تغيير و حذف هدرهاي مربوط به response تنها با استفاده از امكانات IIS7 ميسر است (در حالت integrated pipeline) و IIS6 چنين اجازه‌اي را به ASP.Net نمي‌دهد.
براي اين منظور يك پروژه‌ي جديد، به نام SecurityMdl از نوع class library را ايجاد كرده و دو فايل SecurityMdl.cs و CRemoveHeader.cs را به آن اضافه خواهيم كرد:

//SecurityMdl.cs
using System;
using System.Web;

namespace SecurityMdl
{
public class SecurityMdl : IHttpModule
{
public void Init(HttpApplication app)
{
app.PreSendRequestHeaders += app_PreSendRequestHeaders;
}

static void app_PreSendRequestHeaders(object sender, EventArgs e)
{
CRemoveHeader.CheckPreSendRequestHeaders(sender);
}

public void Dispose() { }
}
}


در اين Http module ، با تغيير اطلاعات دريافتي در روال رخ‌داد گردان PreSendRequestHeaders مي‌توان به مقصود رسيد:

//CRemoveHeader.cs
using System;
using System.Collections.Generic;
using System.Web;

namespace SecurityMdl
{
class CRemoveHeader
{
private static readonly List<string> _headersToRemoveCache
= new List<string>
{
"X-AspNet-Version",
"X-AspNetMvc-Version",
"Server"
};

public static void CheckPreSendRequestHeaders(Object sender)
{
//capture the current request
var currentResponse = ((HttpApplication)sender).Response;

//removing headers
//it only works with IIS 7.x's integrated pipeline
_headersToRemoveCache.ForEach(h => currentResponse.Headers.Remove(h));

//modify the "Server" Http Header
currentResponse.Headers.Set("Server", "Test");
}
}
}
در اينجا علاوه بر حذف هدرهاي ذكر شده در headersToRemoveCache ، هدر Server در پايان كار با يك مقدار جديد نيز ارسال مي‌گردد.
و نهايتا براي استفاده از آن (علاوه بر افزودن ارجاعي به اين ماژول جديد) چند سطر زير را بايد به وب كانفيگ برنامه اضافه كرد:

<system.webServer>
<modules>
<add name="SecurityMdl" type="SecurityMdl.SecurityMdl, SecurityMdl"/>
</modules>

با استفاده از اين روش تمامي هدرهاي مورد نظر بجز هدري به نام X-Powered-By حذف خواهند شد. براي حذف هدر مربوط به X-Powered-By كه توسط خود IIS مديريت مي‌شود بايد موارد زير را به web.config برنامه اضافه كرد:

<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By"/>
</customHeaders>
</httpProtocol>
و يا مي‌توان توسط خود IIS‌ نيز اين مورد را تغيير داد يا كلا حذف نمود:




اكنون پس از اين تغييرات حاصل كار و هدر نهايي دريافت شده از response يك برنامه‌ي ASP.net به شكل زير درخواهد آمد:





براي مطالعه‌ي بيشتر
Remove the X-AspNet-Version header
Cloaking your ASP.NET MVC Web Application on IIS 7
IIS 7 - How to send a custom "Server" http header
Removing Unnecessary HTTP Headers in IIS and ASP.NET
Remove X-Powered-By: ASP.NET HTTP Response Header

۱۳۸۸/۱۰/۱۳

دريافت خطاي database is not accessible و نحوه‌ي رفع مشكل


ممكن است هنگام تلاش جهت اتصال به ديتابيس اس كيوال سرور 2005 به بعد از طريق management studio با پيغام خطاي زير مواجه شويد:
The database XYZ is not accessible. (ObjectExplorer)

و يا اگر بر روي همين ديتابيس كليك راست كرده و به خواص آن مراجعه كنيم، خطاي 952 زير صادر شود:

Database 'XYZ' is in transition. Try the statement later. (Microsoft SQL Server, Error: 952)

اصلا نگران نباشيد؛ هيچ مشكلي نيست!
ابتدا رويه‌ي ذخيره شده‌ي sp_who2 را اجرا كنيد. يك ليست از كانكشن‌هاي باز به ديتابيس‌هاي موجود را به شما خواهد داد.
در اين ليست به دنبال كانكشن‌هاي موجود به ديتابيسي كه اين خطا را مي‌دهد بگرديد. Pid اين كانكشن‌ها را يافته و سپس با دستور kill pid آن‌ها را از بين ببريد. مشكل حل خواهد شد.
عموما نبستن خود management studio سبب اين مشكل مي‌شود. بنابراين حتي يكبار باز و بسته كردن آن نيز بايد اين مشكل را برطرف كند (يا تمام management studio هاي متصل، كه البته راه ساده‌تر همان kill كردن pid آن‌ها است).