گزارش خطا
قالبی را که پیشتر نصب کردید از مسیر زیر حذف کنید
C:\Documents and Settings\Administrator\Local Settings\Application Data\Microsoft\VisualStudio\xyz\Extensions
بعد با نگارش جدید یک قالب جدید درست کنید + نیاز است VS.NET را یکبار بسته و باز کنید.
همان طور که میدانید کاربرد پذیری در خیلی از
پروژهها حرف اول رو میزند و کاربر دوست دارد کارهایی که انجام میدهد خیلی راحت
و با استفاده از موس باشد.یکی از کار هایی که در اکثر پروژهها نیاز است ، چیدمان
ترتیب رکوردها است. ما میخواهیم در این پست ترتیبی اتخاذ کنیم که کاربر بتواند رکوردها را به هر ترتیبی که دوست دارد نمایش دهد.
از توضیحاتی که قبلا دادم مشخص است که این کار احتمالا در ASP.NET WebForm کار سختی نیست ولی این کار باید در MVC از ابتدا طراحی شود.
طرح سوال : یک سری رکورد از یک Table داریم که میخواهیم به ترتیب وارد شدن رکوردها نباشد و ترتیبی که ما میخواهیم نمایش داده شود.
پاسخ کوتاه : خب باید ابتدا یک فیلد (برای اولویت بندی) به Table اضافه کنیم بعد اون فیلد رو بنا به ترتیبی که دوست داریم رکوردها نمایش داده شود پر کنیم (Sort می کنیم ) و در آخر هم هنگام نمایش در View رکوردها را بر اساس این فیلد نمایش میدهیم.
(این پست هم در ادامه پست قبلی در همان پروژه است و از همان Table ها استفاده شده است)
اضافه کردن فیلد :
ابتدا یک فیلد به Table مورد نظر اضافه میکنیم. من اسم این فیلد رو Priority گذاشتم. Table من چنین وضعیتی دارد.
افزودن فایلهای jQuery UI :
در این مرحله شما نیاز دارید فایلهای مورد نیاز برای Sort کردن رکوردها را اضافه کنید. شما میتوانید فقط فایلهای مربوط به Sortable را به صفحه خودتان اضافه کنید و یا مثل من فایل هایی که حاوی تمام قسمتهای jQuery UI هست را اضافه کنید.
من برای این کار از Section استفاده کردم ، ابتدا در Head فایل Layout دو Section تعریف کردم برای CSS و JavaScript . و فایلهای مربوط به Sort کردن را در صفحه ای که باید عمل Sort انجام بشود در این Section ها قرار دادم.
فایل Layout
<head> <meta charset="utf-8" /> @RenderSection("meta", false) <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/~Site.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/redactor/css/redactor.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/css/bootstrap-rtl.min.css")" rel="stylesheet" type="text/css" /> @RenderSection("css", false) <script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Content/js/bootstrap-rtl.js")" type="text/javascript"></script> <script src="@Url.Content("~/Content/redactor/redactor.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script> @RenderSection("js", false) </head>
فایل Index.chtml در پوشه کنترلر Type
@model IEnumerable<KhazarCo.Models.Type> @{ ViewBag.Title = "Index"; Layout = "~/Areas/Administrator/Views/Shared/_Layout.cshtml"; } @section css {<link href="@Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" /> } @section js { <script src="@Url.Content("~/Scripts/jquery-ui-1.9.0.min.js")" type="text/javascript"></script> }
در آخر فایل Index.chtml به اینصورت شده است:
<h2> نوع ها</h2> <p> @Html.ActionLink("ایجاد یک مورد جدید", "Create", null, new { @class = "btn btn-info" }) </p> <table> <thead> <tr> <th> عنوان </th> <th> توضیحات </th> <th> فعال </th> <th> </th> </tr> </thead> <tbody> @foreach (var item in Model.OrderBy(m => m.Priority)) { <tr id="@item.Id"> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @(new HtmlString(item.Description)) </td> <td> @Html.DisplayFor(modelItem => item.IsActive) </td> <td> @Html.ActionLink("ویرایش", "Edit", new { id = item.Id }, new { @class = "btnEdit label label-warning" }) | @Html.ActionLink("مشاهده", "Details", new { id = item.Id }, new { @class = "btnDetails label label-info" }) | @Html.ActionLink("حذف", "Delete", new { id = item.Id }, new { @class = "btnDelete label label-important" }) </td> </tr> } </tbody> </table>
** توجه داشته باشید که من به هر tr یک id اختصاص داده ام که این مقدار id همان مقدار فیلد Id همان رکورد هست ، ما برای مرتب کردن به این Id نیاز داریم (خط 25).
افزودن کدهای کلاینت:
حالا باید کدی بنویسم که دو کار را برای ما انجام دهد : اول حالت Sort پذیری را به سطرهای Table بدهد و دوم اینکه هنگامی که ترتیب سطرهای تغییر کرد ما را با خبر کند:
<script type="text/javascript"> $(function () { $("table tbody").sortable({ helper: fixHelper, update: function (event, ui) { jQuery.ajax('@Url.Action("Sort", "Type", new { area = "Administrator" })', { data: { s: $(this).sortable('toArray').toString() } }); } }).disableSelection(); }); var fixHelper = function (e, ui) { ui.children().each(function () { $(this).width($(this).width()); }); return ui; }; </script>
توضیح کد :
در این کد ما حالت ترتیب پذیری را به Table می دهیم و هنگامی که عمل Update در Table انجام شد تابع مربوطه اجرا میشود. ما در این تایع، ترتیب جدید سطرها را میگیریم ( ** به کمک مقدار Id که به هر سطر دادیم ، این مقدار Id برابر بود با Id خود رکورد در Database ) و به کمکjQuery.ajax به تابع Sort از کنترلر Type در منطقه (area ) Administrator ارسال میکنیم و در آنجا ادامه کار را انجام میدهیم.
تابع fixHelper هم به ما کمک میکند که هنگامی که سطرها از جای خود جدا میشوند ، دارای عرض یکسانی باشند و عرض آنها تغییری نکند.
افزودن کد Server:
حالا باید تابع Sort که مقادیر را به آن ارسال کردیم بنویسم. من این تابع را بر اساس مقداری که از کلاینت ارسال میشود اینگونه طراحی کردم.
public EmptyResult Sort(string s) { if (s != null) { var ids = new List<int>(); foreach (var item in s.Split(',')) { ids.Add(int.Parse(item)); } int intpriority = 0; foreach (var item in ids) { intpriority++; db.Types.Single(m => m.Id == item).Priority = intpriority; } db.SaveChanges(); } return new EmptyResult(); }
در ایتدا مقادیر Id که از کلاینت به صورت String ارسال شده است را میگیریم و بعد به همان ترتیب ارسال در لیستی از int قرار میدهیم ids.
سپس به اضای هر رکورد Type مقدار اولویت را به فیلدی که برای همین مورد اضافه کردیم Priority اختصاص میدهیم. و در آخر هم تغییرات را ذخیره میکنیم. (خود کد کاملا واضح است و نیاری به توضیح بیشتر نیست )
حالا باید هنگامی که لیست Type ها نمایش داده میشود به ترتیب (OrderBy) فیلد Priority نمایش داده شود پس تابع Index را اینطور تغییر میدهیم.
public ViewResult Index() { return View(db.Types.Where(m => m.IsDeleted == false).OrderBy(m => m.Priority)); }
این هم خروجی کار من:
این عکس مربوط به است به قسمت مدیریت پروژه شیرآلات مرجان خزر.
کلاس 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)); } } } }
استفاده از ElmahEfExceptionsLogger جهت طراحی یک Interceptor عمومی
public class ElmahEfInterceptor : EfExceptionsInterceptor { public ElmahEfInterceptor() : base(new ElmahEfExceptionsLogger()) { } }
DbInterception.Add(new ElmahEfInterceptor());
پس از آن جزئیات کلیه استثناهای EF در لاگهای نهایی ELMAH به نحو ذیل ظاهر خواهند شد:
کدهای کامل این پروژه را از اینجا میتوانید دریافت کنید:
ElmahEFLogger
خواندنیهای 12 تیر
اس کیوال سرور
امنیت
توسعه وب
دات نت فریم ورک
دبلیو سی اف
دبلیو پی اف و سیلور لایت
سایتهای ایرانی
شیرپوینت
لینوکس
متفرقه
محیطهای مجتمع توسعه
مرورگرها
مسایل انسانی، اجتماعی و مدیریتی برنامه نویسی
پی اچ پی
وبلاگها ، سایتها و مقالات ایرانی (داخل و خارج از ایران)
- بهبود در توابع Table-Valued
- ظاهر جدید برای ویژوال استودیو 2010
- سورس نرم افزار اشتراک
- فریم ورک های سی اس اس را بهتر بشناسیم
- غزال مایکروسافت در راه است
- بررسی سایت ماهواره امید
- مروری بر سافاری 4
- صدا زدن یک Web service از طریق jquery
- نصب OTRS روی ویندوز ویستا
- آموزش کامل اسکریپت نویسی nsis - ساخت برنامه نصب
- توضیحی اجمالی در مورد singleton pattern
- MySQL Storage Engines
- مشکل بهم ریختگی متون فارسی انگلیسی در کامپیوتر
- ۴۸ نکته و اصل مهم در برنامه نویسی پی اچ پی
- فشرده سازی صفحات در ASP.net
امنیت
Visual Studio
ASP. Net
طراحی و توسعه وب
- ورود به دنیای jQuery plugins
- لیستی از 240 افزونهی جیکوئری
- و همچنین 20 مورد دیگر
- معرفی 13 screengrab webservices
- jQuery Chart Plugins
- برگههای تقلب وبی!
- خودتان را برای IE8 آماده کنید!
PHP
اسکیوال سرور
سی شارپ
عمومی دات نت
- Maestro ، زبان جدید دات نتی برای برنامه نویسی موازی
- چگونه تشخیص دهیم که یک اسمبلی دات نت به چه زبانی نوشته شده است؟
- ADO.NET Data Services v1.5 CTP1
ویندوز
مسایل اجتماعی و انسانی برنامه نویسی
متفرقه
- جایگزین آن ViewComponet است و از لحاظ دسترسی به منابع و سرویسها محدودیتی ندارد. یک مثال
- هنوز هم اگر صرفا نیاز به رندر یک پارشال View را به صورت Ajax ایی دارید، روش زیر کار میکند:
جایی که میخواستید Html.RenderAction را قرار دهید، قطعه کد Ajax ایی زیر را فراخوانی کنید:
<div id="dynamicContentContainer"></div> <script> $.get('@Url.Action("GetData", "Home")', {id : 1}, function(content){ $("#dynamicContentContainer").html(content); }); </script>
[HttpGet] public IActionResult GetData(int id) { return PartialView(id); }
@model int <span>Values from controler :</span> @Model
وقتی بک آپ بگیرید و ریستور کنید همراه بک آپ این اسمبلی هم انقال داده میشود
در اتچ هم به همین شکل
فقط زمانی که از این اسمبلی در توابع و پروسیجرها استفاده میکنید نمیتونید حذفش کنید و در صورت تغیرات باید اسمبلی را به روز کنید.
یک مورد دیگه که من زیاد تو هاستهای شیر شده بهش برخوردم اینه که این امکان توشون فعال نیست و ادمین سرورها هم به سختی این امکان را فعال میکنند پس اگر خواستید از این امکان استفاده کنید ابتدا از فعال بودن آن مطمئن شوید
معرفی Decorator Design Pattern
//Customers want a coffe with double milk and whip beverage=new mocha(beverage); beverage=new mocha(meverage);
در راستای مهاجرت به ویندوز 7، کار نصب و راه اندازی SVN و کلاینتهای آن باید مجددا انجام میشد. اگر برای بار اول است که به مبحث SVN برخورد میکنید، مطالعه این جزوه توصیه میشود. مطالب ذیل برای افرادی مفید است که قصد انتقال سیستم SVN موجود خود را به مکان و یا سیستم عامل دیگری در اسرع وقت دارند.
الف) دریافت و نصب Visual SVN server
یا میتوان SVN خالص را از سایت آن دریافت کرد و یا جهت سهولت کار و همچنین دسترسی به یک کنسول مدیریتی میتوان برنامهی رایگان Visual SVN server را از آدرس زیر دریافت و نصب کرد:
پس از نصب، ابتدا باید یا کاربر جدیدی را جهت استفاده از منابع آن تعریف کرد و یا از نحوهی اعتبار سنجی یکپارچه با ویندوز هم میتوان استفاده کرد که من از این روش دوم استفاده میکنم (شکل زیر، کلیک راست بر روی نود اصلی visual SVN server و سپس انتخاب خواص و مراجعه به برگهی اعتبار سنجی آن):
ب)دریافت و نصب TortoiseSVN
نصب آن نکتهی خاصی ندارد. اما یک سری نکتهی ریز پس از نصب آن بهتر است رعایت شود که در ادامه ذکر میشود:
ج) دریافت و نصب برنامهی WinMerge
برنامهی Diff پیش فرض TortoiseSVN آنچنان قوی نیست. به همین جهت میتوان برنامهی WinMerge را با آن یکپارچه کرد. برای این منظور ابتدا آنرا دریافت نمائید:
اگر پس از نصب TortoiseSVN آنرا نصب کنید، در حین نصب پیشنهاد یکپارچه سازی با TortoiseSVN را نیز میدهد. اگر ابتدا WinMerge را نصب کردهاید و سپس TortoiseSVN بر روی سیستم شما نصب شده، فقط کافی است مطابق شکل زیر ابتدا به قسمت Diff viewers آن مراجعه کرده و سپس با انتخاب گزینهی external ، دستور خط فرمان زیر را وارد نمائید:
بدیهی است مسیر WinMergeU.exe مطابق مسیر نصب در سیستم شما باید تنظیم شود.
د) تنظیم مسیر تحت نظر قرار گرفتن سیستم
TortoiseSVN به صورت پیش فرض کل سیستم را جهت مشاهدهی تغییرات تحت نظر قرار میدهد که گاهی باعث کاهش کارآیی آن خواهد شد. برای رفع این مشکل میتوان مسیرهایی را که پروژههای شما در آن قرار دارند را به آن معرفی نمود تا بار کلی سیستم کاهش یابد.
همانطور که در شکل نیز ملاحظه میکنید، Include path مقدار دهی شده است.
ه) مشخص سازی پسوندهایی که بهتر است از آنها صرفنظر شود
به برگهی general تنظیمات TortoiseSVN مراجعه کرده و در قسمت global ignore pattern آن، موارد زیر را وارد نمائید:
این موارد شامل پروژههای دات نت، دلفی ، VC و امثال آن است و همچنین یک سری فایل بایناری که عموما با پروژههای برنامه نویسی نیازی به ثبت نگارش آنها نیست.
در همین برگه، اگر هنوز از VS2003 استفاده میکنید، تیک مربوط به استفاده از _svn بجای .svn را قرار دهید تا VS.Net با پوشههای مدیریتی ذکر شده مشکل پیدا نکند.
و) نصب افزونههای SVN سازگار با VS.Net
یا میتوان از افزونهی Visual SVN استفاده کرد (که رایگان نیست) و یا AnkhSVN که رایگان و سورس باز است.
ولی در کل یک مورد را بیشتر نصب نکنید. علت هم کند شدن VS.Net است به دلیل فعالیتهای پشت صحنهی هر کدام از این افزونهها که زیاده روی در تعداد آنها گاها باعث کرش هم میشود. بنابراین همان یک مورد کافی است.
ز) Import مخزنهای قبلی
تا اینجا مقدمات کار فراهم شد. اکنون نوبت به import مخزنهای بجا مانده از سیستم قبلی است. برای اینکار مطابق شکل زیر، گزینهی import existing repositories را انتخاب کرده و مسیر مخزنهای قبلی خود را باید معرفی نمود (به ازای هر کدام یکبار باید این عملیات صورت گیرد).
پس از انجام این مراحل یکبار باید سیستم reboot شود و اکنون همه چیز مثل قبل خواهد شد!
نکته:
اگر مسیر ریشه مخزنهای جدید با مسیر آنها در سیستم قبلی متفاوت است، هنگام commit کارهای خود با خطای زیر متوقف خواهید شد:
Unable to open repository 'file:///C:/Repositories/tracking/trunk'
اشکالی ندارد! برای رفع آن باید از گزینهی relocate مربوط به TortoiseSVN استفاده کرد.
بر روی پوشه کاری پروژه خود کلیک راست کرده، انتخاب گزینهی TortoiseSVN و سپس انتخاب گزینهی Relocate آن باید صورت گیرد. در اینجا میتوان مسیر جدید ریشه اصلی مخزن را در سیستم جدید معرفی کرد.