بازخوردهای دوره
ارتباطات بلادرنگ و SignalR
به نظر اسکریپت‌های آن بارگذاری نشده‌اند. در کروم روی دکمه F12 کلیک کنید تا کنسول آن ظاهر شود. بعد بررسی کنید آیا خطایی در برگه network آن گزارش شده یا حتی در کنسول لاگ‌های آن که خطاهای جاوا اسکریپتی را نمایش می‌دهد. با فایرباگ هم می‌شود این نوع برنامه‌ها را دیباگ کرد.
اطلاعات بیشتر: «عیب یابی و دیباگ برنامه‌های SignalR »
همچنین این مثال‌ها را از اینجا نیز می‌توانید دریافت کنید: SignalRSamples.zip  
نظرات مطالب
ASP.NET MVC #11
خلاصه موردی را که عنوان کردید این است:
اگر یک صفحه داریم که از مثلا 4 ویجت نمایش آب و هوا، نمایش اخبار، نمایش تعداد کاربران حاضر در سایت و آمار سایت و نمایش منوی پویای سایت تشکیل شده، تمام این‌ها رو در یک ViewModel قرار ندیدم که اشتباه است. بله این مورد درست است؛ اما ... به معنای نفی استفاده از ViewModel ها نیست.
هر کدام از ویجت‌ها را می‌شود به Partial viewهای مختلفی برای مثال خرد کرد. اما نهایتا هر کدام از این اجزای کلی سیستم اصلی، نیاز به ViewModel دارند که این مورد، بحث اصلی جاری است. یعنی تفاوت قائل شدن بین domain model و view model. پوشه‌ی مدلی که در ساختار پروژه پیش فرض ASP.NET MVC قرار داره در واقع امر یک ViewModel است و نه مدل به معنای تعریف مدل‌های domain سیستم چون قرار است خواص آن مستقیما در View مورد استفاده قرار گیرند.
استفاده از ViewModelها کار را اندکی بیشتر می‌کنند، چون نهایتا خواص آن‌ها باید به مدل اصلی نگاشت شوند اما خوشبختانه برای این مورد هم راه حل هست و روش پیشنهادی، استفاده از کتابخانه‌ی سورس بازی است به نام AutpoMapper :  (^)
نظرات مطالب
Highlight کردن لینک صفحه جاری در ASP.NET MVC
سلام مهندس (تبریک سال نو با تاخیر)
روشی که گفتین به نظر من یه ایراد کوچک داره و اونم اینه که در صورتی لینک رنگی می‌شه که حتما آدرس مورد نظر با آدرس لینک برابر باشه، در صورتی که لینک موردنظر یک صفحه فرعی باشه و ان لینک در لیست منو وجود نداشته باشه هیچ لینکی رنگی نمی‌شه، مثلا در سایت دات نت تیپس در صورتی که کاربر روی لینک جزئیات یک پروژه کلیک کنه لینک پروژه‌ها رنگی میشه در صورتی که ادرسش توی منوها موجود نیست، من وقتی کدهای سایت مذکور بررسی کردم فهمیدم به جای اون شما از تابع startsWith (تعریف شده توسط شما) استفاده کردین، در این صورت لینکهایی که با قسمتی از آدرس مذکور شروع بشه تغییرات رنگ (استایل مورد نظر) رو اون اعمال میشه.
اگر اشتباه می‌کنم لطفا تصحیح بفرمایید.
 
مطالب
ایجاد صفحات راهنما برای ASP.NET Web API
وقتی یک Web API می‌سازید بهتر است صفحات راهنمایی هم برای آن در نظر بگیرید، تا توسعه دهندگان بدانند چگونه باید سرویس شما را فراخوانی و استفاده کنند. گرچه می‌توانید مستندات را بصورت دستی ایجاد کنید، اما بهتر است تا جایی که ممکن است آنها را بصورت خودکار تولید نمایید.

بدین منظور فریم ورک ASP.NET Web API کتابخانه ای برای تولید خودکار صفحات راهنما در زمان اجرا (run-time) فراهم کرده است.


ایجاد صفحات راهنمای API

برای شروع ابتدا ابزار ASP.NET and Web Tools 2012.2 Update را نصب کنید. اگر از ویژوال استودیو 2013 استفاده می‌کنید این ابزار بصورت خودکار نصب شده است. این ابزار صفحات راهنما را به قالب پروژه‌های ASP.NET Web API اضافه می‌کند.

یک پروژه جدید از نوع ASP.NET MVC Application بسازید و قالب Web API را برای آن انتخاب کنید. این قالب پروژه کنترلری بنام ValuesController را بصورت خودکار برای شما ایجاد می‌کند. همچنین صفحات راهنمای API هم برای شما ساخته می‌شوند. تمام کد مربوط به صفحات راهنما در قسمت Areas قرار دارند.

اگر اپلیکیشن را اجرا کنید خواهید دید که صفحه اصلی لینکی به صفحه راهنمای API دارد. از صفحه اصلی، مسیر تقریبی Help/ خواهد بود.

این لینک شما را به یک صفحه خلاصه (summary) هدایت می‌کند.

نمای این صفحه در مسیر Areas/HelpPage/Views/Help/Index.cshtml قرار دارد. می‌توانید این نما را ویرایش کنید و مثلا قالب، عنوان، استایل‌ها و دیگر موارد را تغییر دهید.

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

ستون "API" متد HTTP و آدرس نسبی را لیست می‌کند. ستون "Documentation" مستندات هر API را نمایش می‌دهد. مقادیر این ستون در ابتدا تنها placeholder-text است. در ادامه مقاله خواهید دید چگونه می‌توان از توضیحات XML برای تولید مستندات استفاده کرد.

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


افزودن صفحات راهنما به پروژه ای قدیمی

می توانید با استفاده از NuGet Package Manager صفحات راهنمای خود را به پروژه‌های قدیمی هم اضافه کنید. این گزینه مخصوصا هنگامی مفید است که با پروژه ای کار می‌کنید که قالب آن Web API نیست.

از منوی Tools گزینه‌های Library Package Manager, Package Manager Console را انتخاب کنید. در پنجره Package Manager Console فرمان زیر را وارد کنید.

Install-Package Microsoft.AspNet.WebApi.HelpPage
این پکیج اسمبلی‌های لازم برای صفحات راهنما را به پروژه اضافه می‌کند و نماهای MVC را در مسیر Areas/HelpPage می‌سازد. اضافه کردن لینکی به صفحات راهنما باید بصورت دستی انجام شود. برای اضافه کردن این لینک به یک نمای Razor از کدی مانند لیست زیر استفاده کنید.

@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)

همانطور که مشاهده می‌کنید مسیر نسبی صفحات راهنما "Help/" می‌باشد. همچنین اطمینان حاصل کنید که ناحیه‌ها (Areas) بدرستی رجیستر می‌شوند. فایل Global.asax را باز کنید و کد زیر را در صورتی که وجود ندارد اضافه کنید.
protected void Application_Start()
{
    // Add this code, if not present.
    AreaRegistration.RegisterAllAreas();

    // ...
}

افزودن مستندات API

بصورت پیش فرض صفحات راهنما از placeholder-text برای مستندات استفاده می‌کنند. می‌توانید برای ساختن مستندات از توضیحات XML استفاده کنید. برای فعال سازی این قابلیت فایل Areas/HelpPage/App_Start/HelpPageConfig.cs را باز کنید و خط زیر را از حالت کامنت درآورید:

config.SetDocumentationProvider(new XmlDocumentationProvider(
    HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
حال روی نام پروژه کلیک راست کنید و Properties را انتخاب کنید. در پنجره باز شده قسمت Build را کلیک کنید.

زیر قسمت Output گزینه XML documentation file را تیک بزنید و در فیلد روبروی آن مقدار "App_Data/XmlDocument.xml" را وارد کنید.

حال کنترلر ValuesController را از مسیر Controllers/ValuesController.cs/ باز کنید و یک سری توضیحات XML به متدهای آن اضافه کنید. بعنوان مثال:

/// <summary>
/// Gets some very important data from the server.
/// </summary>
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

/// <summary>
/// Looks up some data by ID.
/// </summary>
/// <param name="id">The ID of the data.</param>
public string Get(int id)
{
    return "value";
}

اپلیکیشن را مجددا اجرا کنید و به صفحات راهنما بروید. حالا مستندات API شما باید تولید شده و نمایش داده شوند.

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


توضیحات تکمیلی

صفحات راهنما توسط کلاس ApiExplorer تولید می‌شوند، که جزئی از فریم ورک ASP.NET Web API است. به ازای هر API این کلاس یک ApiDescription دارد که توضیحات لازم را در بر می‌گیرد. در اینجا منظور از "API" ترکیبی از متدهای HTTP و مسیرهای نسبی است. بعنوان مثال لیست زیر تعدادی API را نمایش می‌دهد:

  • GET /api/products
  • {GET /api/products/{id
  • POST /api/products

اگر اکشن‌های کنترلر از متدهای متعددی پشتیبانی کنند، ApiExplorer هر متد را بعنوان یک API مجزا در نظر خواهد گرفت. برای مخفی کردن یک API از ApiExplorer کافی است خاصیت ApiExplorerSettings را به اکشن مورد نظر اضافه کنید و مقدار خاصیت IgnoreApi آن را به true تنظیم نمایید.

[ApiExplorerSettings(IgnoreApi=true)]
public HttpResponseMessage Get(int id) {  }

همچنین می‌توانید این خاصیت را به کنترلر‌ها اضافه کنید تا تمام کنترلر از ApiExplorer مخفی شود.

کلاس ApiExplorer متن مستندات را توسط اینترفیس IDocumentationProvider دریافت می‌کند. کد مربوطه در مسیر Areas/HelpPage/XmlDocumentation.cs/ قرار دارد. همانطور که گفته شد مقادیر مورد نظر از توضیحات XML استخراج می‌شوند. نکته جالب آنکه می‌توانید با پیاده سازی این اینترفیس مستندات خود را از منبع دیگری استخراج کنید. برای اینکار باید متد الحاقی SetDocumentationProvider را هم فراخوانی کنید، که در HelpPageConfigurationExtensions تعریف شده است.

کلاس ApiExplorer بصورت خودکار اینترفیس IDocumentationProvider را فراخوانی می‌کند تا مستندات API‌ها را دریافت کند. سپس مقادیر دریافت شده را در خاصیت Documentation ذخیره می‌کند. این خاصیت روی آبجکت‌های ApiDescription و ApiParameterDescription تعریف شده است.


مطالعه بیشتر

نظرات مطالب
دادن «حق فراموش شدن» به کاربران در ASP.NET Core Identity 2.1
سلام و تشکر
در مورد "قسمتی را هم در آن درنظر بگیرید که کاربر با فشردن یک کلیک، بتواند اکانت فعلی خودش را برای همیشه محو و نابود کند؛ بدون اینکه اثری از آن باقی بماند "
دو سوال داشتم.
ممکنه آی دی کاربر به صورت کلید خارجی در جداول دیگر استفاده شده باشه. در اینصورت وقتی بخواهیم اطلاعات کاربر را حذف کنیم چطور باید این مشکل فعالیت‌های کاربر که به صورت کلید خارجی در جداول دیگر داریم رو حذف نکنیم؟ مثلا در همین سایت اگر من مطالبی ثبت کرده باشم و بخواهم اکانتم رو حذف کنم باید اون مطالبی هم که قبلا در سایت ثبت کردم کاملا حذف بشه؟ اگر اینطوری باشه به نظرم یه ایرادت دیگری به وجود میاد.

همینطور در مورد "
با کلیک بر روی یک دکمه، کلیه اطلاعات شخصی خودش را دانلود و ذخیره کند."

این اطلاعات به صورت Json برای کاربر نمایش داده میشه تا دانلود کنه. خوب امکان برعکسش هم باید داشته باشیم؟ یعنی مثلا من در سایتی  اکانتم رو حذف کرده بودم ولی حالا به دلایلی میخوام اکانتم رو دوباره برگردانم [شبیه اینستاگرام] باید اون فایل Json رو دوباره روی سایت آپلود کنم تا همان اطلاعات کاربری قبلی ام را برگردان کند؟

مطالب
روشی سریع برای ایجاد RSS و Sitemap در ASP.NET MVC
برای مطالعه روش‌های بدست آوردن خروجی xml مربوط به Rss و Sitemap،  میتوانید از مقالات مشخص شده استفاده کنید .[اینجا] و [اینجا].

در صورتیکه طراحی شما بر اساس MVC صورت گرفته است، در کمتر از چند دقیقه و در سه مرحله میتوانید پرونده Rss و Sitemap را برای همیشه ببندید. 

پیش از تشریح مراحل، به ساختار این دو فایل توجه کنید. 

مراحل کار : 

مرحله 1. ایجاد نوع(Type) مورد نیاز برای ایجاد Xml ‌های فوق

مرحله 2 . ایجاد کنترلر XML

مرحله 3. ایجاد مسیریابی(Routing)


مرحله 1 : ابتدا یک کلاس به منظور شکل دهی به اطلاعات، بر اساس خواسته‌های xml مرتبط با RSS و Sitemap تشکیل دهید:

public class PostToXml
    {
        
        public int PostId { get; set; }

        public string title { get; set; }

        public string link { get; set; }
        
        public string description { get; set; }

        public Nullable<DateTime> pubDate { get; set; }

      
    }

مرحله 2 : یک کنترلر به نام xml ایجاد کنید و اکشن متدهای زیر را درون آن قرار دهید :

       public ContentResult RSS()
        {
            
            var items = GetRssFeed();
            var rss = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
              new XElement("rss",
                new XAttribute("version", "2.0"),
                  new XElement("channel",
                    new XElement("title", "آخرین مطالب سایت"),
                    new XElement("link", "http://" + Request.Url.Host+"/rss"),
                    new XElement("description", "آخرین مطالب سایت من"),
                    new XElement("copyright","(c)" + DateTime.Now.Year + ", نام سایت من.تمامی حقوق محفوظ است"),
                  from item in items
                  select
                  new XElement("item",
                    new XElement("title", item.title),
                    new XElement("description", item.description),
                    new XElement("link", item.link),
                    new XElement("pubDate", item.pubDate)

                  )
                )
              )
            );
            return Content(rss.ToString(), "text/xml");
        }



        public ContentResult Sitemap()
        {
            XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
            var items = GetLinks();
            var sitemap = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
                new XElement(ns + "urlset",
                    from item in items
                    select
                    new XElement("url",
                      new XElement("loc", item.link),
                      new XElement("changefreq", "monthly"),
                      new XElement("priority", "0.5")
                      )
                    )
                  );
            return Content(sitemap.ToString(), "text/xml");
        }


        public IEnumerable<PostToXml> GetRssFeed()
        {
          // یک کوئری که لیستی از تایپ مشخص شده به ما بدهد
        }

         public IEnumerable<PostToXml> GetLinks()
        {
            // یک کوئری که لیستی از تایپ مشخص شده به ما بدهد
        }

این کنترلر دارای دو اکشن متد Rss و Sitemap است و این اکشن‌ها وظیفه‌ی ایجاد فایل‌های Xml را به عهده دارند. مواد اولیه این xml ‌ها از دو متد GetRssFeed و GetLinks تهیه می‌شوند. ما این مواد را در تمپلیت Rss و Sitemap جایگذاری خواهیم کرد. (به کمک دو اکشن متد Rss و Sitemap )

کافیست لیستی از مواردی را که می‌خواهیم در Rss یا Sitemap ثبت شوند، تهیه کنیم. این لیست بر اساس شکل تنظیم دیتابیس و مسیریابی سایت، می‌تواند پیچیده و یا ساده باشد. (به کمک کوئری گرفتن با linq و یا اضافه کردن مستقیم آدرس‌ها به لیست و یا ترکیبی از هر دو مورد) برای درک بهتر موضوع، لطفا تصویر موجود در ابتدای مقاله را مشاهده نمایید.

مرحله 3 : در مرحله آخر کافیست دو مورد زیر را به فایل RoutConfig.cs بیافزایید: 

routes.MapRoute(
              "Sitemap", "sitemap",
              new { controller = "XML", action = "Sitemap" });
 routes.MapRoute(
              "RSS", "rss",
               new { controller = "XML", action = "RSS" });

به کمک آدرس‌های زیر می‌توانید به آنچه که تهیه کرده‌اید دسترسی داشته باشید :

http://domain.com/rss
http://domain.com/sitemap  

فایل پروژه را دریافت کنید :

MVC_RSS_Sitemap-43ad3c6681734b34b91deaaabcdba871.rar 

نظرات مطالب
Debugger visualizers
جدید

سلام

خبرخوان (تکست و گرافیکی)، لیست و فید وبلاگ‌های «آی تی» ارائه شده است که وبلاگ شما نیز جز آنها قرار گرفته است.

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

http://persianbloggers.blogspot.com/2008/12/it-p.html

پرشین بلاگرز شما را به بازدید و استفاده از این خبرخوان و 24 خبرخوان دیگر موجود دعوت می‌کند.
بازخوردهای دوره
مدیریت نگاشت ConnectionIdها در SignalR به کاربران واقعی سیستم
با سلام؛ چطور میشه تو signalr2 متد OnDisconnected() رو وقتی رو دکمه ای کلیک میکنیم فراخوانی کرد؟
در ضمن این کد هم کار نمیکنه.
window.onbeforeunload = function (e) {
    $.connection.hub.stop();
};
یه سوال دیگه : فرض کنید چند تا تب مرورگر باز باشه و کاربر به سیستم لاگین کرده باشه و چند صفحه مختلف سایت باز باشه. اگه قرار باشه با بستن هر تب رویداد Ondisconnected() فراخوانی بشه و کاربر جاری از لیست کاربران آنلاین حذف بشه در صورتی که تب دیگه ای باز باشه چطور میشه آمار کاربران آنلاین رو داشت؟
به صورت کلی چطور میتونم زمانی که کاربر دکمه خروج رو میزنه یکی از کاربران آنلاین رو از لیست کاربران آنلاین حذف کنم. و اینکه اگه کاربر دکمه خروج و نزنه و همه تب‌های مرورگر خودش و که مربوط به سایت ماست ببنده جطور مدیریت میشه؟
اشتراک‌ها
نظرات اسپم و روش جلوگیری از آن‌ها

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

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

نظرات اسپم و روش جلوگیری از آن‌ها