2012/01/31

‫خطایابی در WCF

log گیری در بیشتر برنامه‌های می‌تواند خطاهایی را که هیچ کس موفق به کشف آن نشده است را پیدا کند. WCF هم در این مورد استثنا نیست. در WCF اگر بخواهید یک enum را از طریق سرویس‌ها انتقال دهید باید روی تک تک اعضای آن از اتریبیوت [EnumMember] استفاده کنید. من یک جا به جای استفاده از [EnumMember] از [DataMember] که مخصوص اعضای کلاس است استفاده کرده بودم. به چیزهایی خیلی زیادی شک کرده بودم، همه آنها را امتحان کردم، از روش‌های مختلف دیباگ هم استفاده کردم ولی نفهمیدم که علت مشکل An existing connection was forcibly closed by the remote host چیست.

خدا به گردانندگان و کاربران SO خیر بدهد. از طریق یکی از سوالات SO ترغیب شدم که لاگ WCF را فعال کنم. خوشبختانه لاگ تولید شده به من گفت که مشکل از کجاست. فعال کردن لاگ WCF خیلی ساده است، در حد اضافه کردن چند خط به app.config. لطفاً نگاهی به اینجا بیندازید.









2012/01/22

‫Templify چیست؟

آیا شما هم از جمله کسانی هستید که هر چند وقت یک بار در شرکت‌تان یک پروژه جدید را new کرده و کار را با کپی کردن از یک سورس پایه و تغییر قسمت‌های مختلف آن از جمله نام پروژه، namespace، اسامی موجود در web.config و غیره ادامه می‌دهید؟ آیا از انجام این کار تکراری خسته شده‌اید؟ آیا اشتباهات ضمنی این کپی کاری آبروی شما را چندین بار در شرکت برده است؟ اگر جواب همه این سوالات مثبت است بهتر است نگاهی به ابزار Templify بیندازید.

Templify ابزاری است که در نگاه اول کارش شبیه به Templateهای ایجاد پروژه در Visual Studio و ابزار NuPack به نظر می‌رسد. اما سازندگان این ابزار مدعی هستند Templify کارهایی می‌کند که دو ابزار فوق در انجام آن مشکل دارند. کار Templify ایجاد یک پروژه جدید بر اساس Templateهای از پیش تعریف شده است. فرض کنید پروژه‌ی پایه‌ای که هر روز در شرکت با آن سر و کار دارید یک Visual Studio Solution است که از چند Visual Studio Project با نام‌های BaseProj.Core، BaseProj.Web و BaseProj.Test تشکیل شده است. شما می‌توانید این solution را به صورت یک package به Templify معرفی کنید. من بعد می‌توانید با سادگی چند کلیک از Templify بخواهید که instance جدیدی از این پروژه برای شما بسازد. Templify یک نام از شما می‌گیرد و نام پروژه، namespaceها و دیگر موارد مشابه را خودش تغییر می‌دهد. مثلا اگر نام مورد نظر شما MyProj باشد، نام پروژه‌ها و اسمبلی‌ها و غیره به MyProj.Core، MyProj.Web و MyProj.Test تغییر می‌یابد. برای دیدن یک راهنمای خوب به اینجا مراجعه کنید. صفحه اصلی Templify هم در اینجا قرار دارد.







2012/01/11

‫راه افتادن در ASP.NET MVC و jQuery

به خاطر پروژه‌ای که درگیرش هستم باید ASP.NET MVC و jQuery را هم بلد باشم. بخش MVC پروژه خیلی وقت است که شروع شده ولی jQuery آن تازه به جریان افتاده است. اولین استفاده از jQuery مربوط به است به نمایش یک Popup و دریافت اطلاعات از طریق آن. هنوز دستم در MVC و jQuery آنقدر راه نیفتاده که بتوانم در مورد بخشی از آن چیزی بنویسم ولی انتقال اولین تجربه‌های این دو خالی از لطف نیست.

استفاده از MVC برای کسی که مدت‌ها برنامه‌نویس ASP.NET WebForm بوده تجربه دلهره‌آوری است. از روی شنیده‌ها می‌دانستم که MVC بخشی از کارهای خودکار WebForm را که باعث جدایی برنامه‌نویس و ماهیت طبیعی HTML و Web شده بود را حذف کرده است. یعنی در MVC از یک جایی به بعد این خود برنامه‌نویس است که باید ارتباط Server و Client را برقرار کند. هر چقدر که پروژه بیشتر جلو می‌رفت حس می‌کردم که فاصله‌ام با جدایی موعود کمتر و کمتر می‌شود. حسی شبیه به take-off هواپیما از روی زمین، با کمی اغراق.

فکر می‌کنم که دیروز این لحظه جدایی فرا رسید و من یاد گرفتم که چطور یک Form را با کمک Html.BeginForm در MVC بسازم، اطلاعات آن را با کمک ‎$("#FormId").serialize()‎ و ‎$.post()‎ در jQuery به سرور ارسال کنم و در نهایت در سرور با استفاده از متودی در Controllerهای تعریف شده MVC سمت سرور اطلاعات را دریافت کرده و مورد پردازش قرار دهم.

حالا که آن دلهره را پشت سر گذاشته‌ام (اقلاً بخشی از آن را)، آن حس تبدیل به حسی شیرین و ظفرمندانه شده است. علاوه بر این حس می‌کنم بعد از مدت‌ها توانسته‌ام با کد client side آشتی کرده و با احترام با آن برخورد کنم. در این رابطه باید ممنون پروژه و راهنمایی مفید یک سایت باشم.




2012/01/10

ارتباطات شبه دو طرفه

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

از طرف دیگر مزایای تویتر و… بیش از آن است که بتواند به سادگی اجازه قطع آنها را بدهد. شخصاً:

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


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

برای رفع این مشکل می‌خواهم از روش ارتباطات شبه دو طرفه (یک و نیم طرفه) استفاده کنم. یعنی هر نوع تویت یا updateی را در همان لحظه تبادر به ذهن ارسال کنم ولی بازخورد (واکنش دوستان، followerها و…) را فقط شب به شب نگاه کرده و جواب می‌دهم. برای ارسال هم صرفا از ابزارهای یک طرفه مثل «ایمیل به تویتر» و «SMS به تویتر» استفاده می‌کنم.



* * *

پ.ن. ۱: همینجا از دوستانی که ممکن است به «بازخوردشان» با زمان طولانی جواب بدهم عذرخواهی می‌کنم.
پ.ن. ۲: حساب تویتر من mohebbi است.




2012/01/08

‫مشکل عدم شناخت UpdatePanel توسط ویژوال استودیو

آنهایی که از اوایل Ajax در ASP.NET که با اسم رمز Atlas آغاز شد کار با آن را شروع کردند خوب می‌دانند که مایکروسافت چندین و چند بار اسم پروژه، Namesapceها، نام dll، شماره version و حتی بود و نبودش را در دل ‎.Net Framework عوض کرده است. ظاهراً هنوز هم مشکلات ویژوال استودیو با مجموعه UpdatePanel/ScriptManager و… حل نشده است.

در یک Class Library چند فایل ascx داشتیم که داخل آنها از UpdatePanel و ScriptManager استفاده شده بود. به دلیل یک تغییر اسم کلی همه این فایل‌ها را یک بار باز و بسته کرده بودم و دقیقاً از همان لحظه دچار مشکل شده بودم. چون ویژوال استودیو نمی‌توانست پروژه را Build کند. عنوان خطا این بود که ویژوال استودیو نمی‌تواند System.Web.UI.WebControls.UpdatePanel را در dllهای موجود پیدا کند. چندین و چند بار رفرنس‌های System.Web و System.Web.Extensions را پاک کرده و دوباره اضافه کردم ولی مشکل حل نشد.

نهایتاً گره این مشکل با راهنمایی یکی از دوستان خوب و دقیق ما یعنی سامان باز شد. این مشکل یک باگ شناخته شده ویژوال استودیو ۲۰۱۰ است. وقتی که فایل ascx (یا aspx) در ویژوال استودیو باز می‌شود، خود ویژوال استودیو به اشتباه namespace مربوط به UpdatePanel و بقیه را به System.Web.UI.WebControls.UpdatePanel تغییر می‌دهد در حالی که درست آن System.Web.UI.UpdatePanel است. یعنی تیکه WebControls اضافی بوده است. من این مشکل را در designer مشاهده کرده‌ام.




‫‫View به عنوان یک Domain Entity در Castle ActiveRecord

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

[ActiveRecord("SampleView")]
    public class SampleDomain : ActiveRecordBase<SampleDomain>
    {
        [Property]
        public virtual string Prop1 { set; get; }

        [Property]
        public virtual string Prop2 { set; get; }
    }
در اینجا SampleView نام View دیتابیسی است و Prop1 و Prop2 نام دو تا از ستون‌های آن است.

اما اگر ما یک Entity پایه داشتیم و حتماً باید همه Entityها از آن Entity پایه ارث‌بری می‌کردند چه باید می‌کردیم؟ Entityهای پایه معمولا دارای Propertyهای مشترکی مثل Id و LastModifyDate هستند. فرض کنید اسم آن Entity پایه EntityBase بود. آن وقت Domain Entity مورد نظر به شکل زیر در می‌آمد:

[ActiveRecord("SampleView")]
    public class SampleDomain : BaseEntity<SampleDomain>
    {
        [Property]
        public virtual string Prop1 { set; get; }

        [Property]
        public virtual string Prop2 { set; get; }
    }
تنها تفاوتی که به وجود آمد ارث‌بری از BaseEntity به جای خود ActiveRecordBase بود. البته View دیتابیسی مورد نظر باید شامل همه Propertyهای مشترک تعریف شده در BaseEntity هم باشد مثل Id و LastModifyDate.