اشتراک‌ها
نمایش لیست کشورها به همراه پرچم آنها به صورت dropdown با استفاده از select2
بعد از دانلود و افزودن  select2 ، برای پرچم‌ها سراغ semantic-ui  می‌رویم و بعد از دانلود آن، فایل flag.min.css در آدرس Semantic-Ui/components/flag.min.css را به پروژه اضافه می‌کنیم.
<div>
    <div>
        <select ></select>
    </div>
</div>

 $(document).ready(function () {

            $('.js-example-basic-single').select2({
                data: [
                    { id: "al", text: "Albania" },
                    { id: "dz", text: "Algeria" },
                    { id: "as", text: "American Samoa" },
                    { id: "ad", text: "Andorra" },
                    { id: "ao", text: "Angola" },
                    { id: "ai", text: "Anguilla" },
                    { id: "ag", text: "Antigua" },
                    { id: "ar", text: "Argentina" },
                    { id: "am", text: "Armenia" },
                    { id: "aw", text: "Aruba" },
                    { id: "au", text: "Australia" },
                    { id: "at", text: "Austria" },
                    { id: "az", text: "Azerbaijan" },
                    { id: "bs", text: "Bahamas" },
                    { id: "bh", text: "Bahrain" },
                    { id: "bd", text: "Bangladesh" },
                    { id: "bb", text: "Barbados" },
                    { id: "by", text: "Belarus" },
                    { id: "be", text: "Belgium" },
                    { id: "bz", text: "Belize" },
                    { id: "bj", text: "Benin" },
                    { id: "bm", text: "Bermuda" },
                    { id: "bt", text: "Bhutan" },
                    { id: "bo", text: "Bolivia" },
                    { id: "ba", text: "Bosnia" },
                    { id: "bw", text: "Botswana" },
                    { id: "bv", text: "Bouvet Island" },
                    { id: "br", text: "Brazil" },
                    { id: "vg", text: "British Virgin Islands" },
                    { id: "bn", text: "Brunei" },
                    { id: "bg", text: "Bulgaria" },
                    { id: "bf", text: "Burkina Faso" },
                    { id: "mm", text: "Burma" },
                    { id: "bi", text: "Burundi" },
                    { id: "tc", text: "Caicos Islands" },
                    { id: "kh", text: "Cambodia" },
                    { id: "cm", text: "Cameroon" },
                    { id: "ca", text: "Canada" },
                    { id: "cv", text: "Cape Verde" },
                    { id: "ky", text: "Cayman Islands" },
                    { id: "cf", text: "Central African Republic" },
                    { id: "td", text: "Chad" },
                    { id: "cl", text: "Chile" },
                    { id: "cn", text: "China" },
                    { id: "cx", text: "Christmas Island" },
                    { id: "cc", text: "Cocos Islands" },
                    { id: "co", text: "Colombia" },
                    { id: "km", text: "Comoros" },
                    { id: "cg", text: "Congo Brazzaville" },
                    { id: "cd", text: "Congo" },
                    { id: "ck", text: "Cook Islands" },
                    { id: "cr", text: "Costa Rica" },
                    { id: "ci", text: "Cote Divoire" },
                    { id: "hr", text: "Croatia" },
                    { id: "cu", text: "Cuba" },
                    { id: "cy", text: "Cyprus" },
                    { id: "cz", text: "Czech Republic" },
                    { id: "dk", text: "Denmark" },
                    { id: "dj", text: "Djibouti" },
                    { id: "dm", text: "Dominica" },
                    { id: "do", text: "Dominican Republic" },
                    { id: "ec", text: "Ecuador" },
                    { id: "eg", text: "Egypt" },
                    { id: "sv", text: "El Salvador" },
                    { id: "gb", text: "England" },
                    { id: "gq", text: "Equatorial Guinea" },
                    { id: "er", text: "Eritrea" },
                    { id: "ee", text: "Estonia" },
                    { id: "et", text: "Ethiopia" },
                    { id: "eu", text: "European Union" },
                    { id: "fk", text: "Falkland Islands" },
                    { id: "fo", text: "Faroe Islands" },
                    { id: "fj", text: "Fiji" },
                    { id: "fi", text: "Finland" },
                    { id: "fr", text: "France" },
                    { id: "gf", text: "French Guiana" },
                    { id: "pf", text: "French Polynesia" },
                    { id: "tf", text: "French Territories" },
                    { id: "ga", text: "Gabon" },
                    { id: "gm", text: "Gambia" },
                    { id: "ge", text: "Georgia" },
                    { id: "de", text: "Germany" },
                    { id: "gh", text: "Ghana" },
                    { id: "gi", text: "Gibraltar" },
                    { id: "gr", text: "Greece" },
                    { id: "gl", text: "Greenland" },
                    { id: "gd", text: "Grenada" },
                    { id: "gp", text: "Guadeloupe" },
                    { id: "gu", text: "Guam" },
                    { id: "gt", text: "Guatemala" },
                    { id: "gw", text: "Guinea-Bissau" },
                    { id: "gn", text: "Guinea" },
                    { id: "gy", text: "Guyana" },
                    { id: "ht", text: "Haiti" },
                    { id: "hm", text: "Heard Island" },
                    { id: "hn", text: "Honduras" },
                    { id: "hk", text: "Hong Kong" },
                    { id: "hu", text: "Hungary" },
                    { id: "is", text: "Iceland" },
                    { id: "in", text: "India" },
                    { id: "io", text: "Indian Ocean Territory" },
                    { id: "id", text: "Indonesia" },
                    { id: "ir", text: "Iran" },
                    { id: "iq", text: "Iraq" },
                    { id: "ie", text: "Ireland" },
                    { id: "il", text: "Israel" },
                    { id: "it", text: "Italy" },
                    { id: "jm", text: "Jamaica" },
                    { id: "jp", text: "Japan" },
                    { id: "jo", text: "Jordan" },
                    { id: "kz", text: "Kazakhstan" },
                    { id: "ke", text: "Kenya" },
                    { id: "ki", text: "Kiribati" },
                    { id: "kw", text: "Kuwait" },
                    { id: "kg", text: "Kyrgyzstan" },
                    { id: "la", text: "Laos" },
                    { id: "lv", text: "Latvia" },
                    { id: "lb", text: "Lebanon" },
                    { id: "ls", text: "Lesotho" },
                    { id: "lr", text: "Liberia" },
                    { id: "ly", text: "Libya" },
                    { id: "li", text: "Liechtenstein" },
                    { id: "lt", text: "Lithuania" },
                    { id: "lu", text: "Luxembourg" },
                    { id: "mo", text: "Macau" },
                    { id: "mk", text: "Macedonia" },
                    { id: "mg", text: "Madagascar" },
                    { id: "mw", text: "Malawi" },
                    { id: "my", text: "Malaysia" },
                    { id: "mv", text: "Maldives" },
                    { id: "ml", text: "Mali" },
                    { id: "mt", text: "Malta" },
                    { id: "mh", text: "Marshall Islands" },
                    { id: "mq", text: "Martinique" },
                    { id: "mr", text: "Mauritania" },
                    { id: "mu", text: "Mauritius" },
                    { id: "yt", text: "Mayotte" },
                    { id: "mx", text: "Mexico" },
                    { id: "fm", text: "Micronesia" },
                    { id: "md", text: "Moldova" },
                    { id: "mc", text: "Monaco" },
                    { id: "mn", text: "Mongolia" },
                    { id: "me", text: "Montenegro" },
                    { id: "ms", text: "Montserrat" },
                    { id: "ma", text: "Morocco" },
                    { id: "mz", text: "Mozambique" },
                    { id: "na", text: "Namibia" },
                    { id: "nr", text: "Nauru" },
                    { id: "np", text: "Nepal" },
                    { id: "an", text: "Netherlands Antilles" },
                    { id: "nl", text: "Netherlands" },
                    { id: "nc", text: "New Caledonia" },
                    { id: "pg", text: "New Guinea" },
                    { id: "nz", text: "New Zealand" },
                    { id: "ni", text: "Nicaragua" },
                    { id: "ne", text: "Niger" },
                    { id: "ng", text: "Nigeria" },
                    { id: "nu", text: "Niue" },
                    { id: "nf", text: "Norfolk Island" },
                    { id: "kp", text: "North Korea" },
                    { id: "mp", text: "Northern Mariana Islands" },
                    { id: "no", text: "Norway" },
                    { id: "om", text: "Oman" },
                    { id: "pk", text: "Pakistan" },
                    { id: "pw", text: "Palau" },
                    { id: "ps", text: "Palestine" },
                    { id: "pa", text: "Panama" },
                    { id: "py", text: "Paraguay" },
                    { id: "pe", text: "Peru" },
                    { id: "ph", text: "Philippines" },
                    { id: "pn", text: "Pitcairn Islands" },
                    { id: "pl", text: "Poland" },
                    { id: "pt", text: "Portugal" },
                    { id: "pr", text: "Puerto Rico" },
                    { id: "qa", text: "Qatar" },
                    { id: "re", text: "Reunion" },
                    { id: "ro", text: "Romania" },
                    { id: "ru", text: "Russia" },
                    { id: "rw", text: "Rwanda" },
                    { id: "sh", text: "Saint Helena" },
                    { id: "kn", text: "Saint Kitts and Nevis" },
                    { id: "lc", text: "Saint Lucia" },
                    { id: "pm", text: "Saint Pierre" },
                    { id: "vc", text: "Saint Vincent" },
                    { id: "ws", text: "Samoa" },
                    { id: "sm", text: "San Marino" },
                    { id: "gs", text: "Sandwich Islands" },
                    { id: "st", text: "Sao Tome" },
                    { id: "sa", text: "Saudi Arabia" },
                    { id: "sn", text: "Senegal" },
                    { id: "cs", text: "Serbia" },
                    { id: "rs", text: "Serbia" },
                    { id: "sc", text: "Seychelles" },
                    { id: "sl", text: "Sierra Leone" },
                    { id: "sg", text: "Singapore" },
                    { id: "sk", text: "Slovakia" },
                    { id: "si", text: "Slovenia" },
                    { id: "sb", text: "Solomon Islands" },
                    { id: "so", text: "Somalia" },
                    { id: "za", text: "South Africa" },
                    { id: "kr", text: "South Korea" },
                    { id: "es", text: "Spain" },
                    { id: "lk", text: "Sri Lanka" },
                    { id: "sd", text: "Sudan" },
                    { id: "sr", text: "Suriname" },
                    { id: "sj", text: "Svalbard" },
                    { id: "sz", text: "Swaziland" },
                    { id: "se", text: "Sweden" },
                    { id: "ch", text: "Switzerland" },
                    { id: "sy", text: "Syria" },
                    { id: "tw", text: "Taiwan" },
                    { id: "tj", text: "Tajikistan" },
                    { id: "tz", text: "Tanzania" },
                    { id: "th", text: "Thailand" },
                    { id: "tl", text: "Timorleste" },
                    { id: "tg", text: "Togo" },
                    { id: "tk", text: "Tokelau" },
                    { id: "to", text: "Tonga" },
                    { id: "tt", text: "Trinidad" },
                    { id: "tn", text: "Tunisia" },
                    { id: "tr", text: "Turkey" },
                    { id: "tm", text: "Turkmenistan" },
                    { id: "tv", text: "Tuvalu" },
                    { id: "ug", text: "Uganda" },
                    { id: "ua", text: "Ukraine" },
                    { id: "ae", text: "United Arab Emirates" },
                    { id: "us", text: "United States" },
                    { id: "uy", text: "Uruguay" },
                    { id: "um", text: "Us Minor Islands" },
                    { id: "vi", text: "Us Virgin Islands" },
                    { id: "uz", text: "Uzbekistan" },
                    { id: "vu", text: "Vanuatu" },
                    { id: "va", text: "Vatican City" },
                    { id: "ve", text: "Venezuela" },
                    { id: "vn", text: "Vietnam" },
                    { id: "wf", text: "Wallis and Futuna" },
                    { id: "eh", text: "Western Sahara" },
                    { id: "ye", text: "Yemen" },
                    { id: "zm", text: "Zambia" },
                    { id: "zw", text: "Zimbabwe" }
                ],
                placeholder: "کشور مورد نظرتان را انتخاب نمایید",
                language: "fa",
                theme: "bootstrap",
                dir: "rtl",
                tokenSeparators: [',', ' '],
                multiple: false,
                templateResult:format,
                templateSelection: format,
                escapeMarkup: function (m) { return m; }
            });

        });
    </script>
در اینجا ما اطلاعات را به صورت دستی وارد کرده ایم. شما می‌توانید این اطلاعات را از سمت سرور دریافت نمایید.
در templateResult و templateSelection شما می‌توانید ساختار مورد نظرتان را پیاده سازی کنید. اولی در لیستی از dropdown به عنوان یک option و دومی وقتی که انتخاب می‌شود.
تابع fotmat به صورت زیر می‌باشد.
 function format(state) {
            var $state = $(
                '<span>' + state.text + ' <i class="' + state.id + ' flag"> ' +
                '</i></span>'
            );
            return $state;
        };

لازم به ذکر است کلاس لازم برای ایجاد  پرچم کشوری مثل ایران با استفاده از Semantic-Ui به صورت زیر می‌باشد.
<i class="ir flag"></i>
و در نهایت خروجی آن به شکل زیر می‌باشد

نمایش لیست کشورها به همراه پرچم آنها به صورت dropdown با استفاده از select2
اشتراک‌ها
بهبود کارآیی IDEهای Jetbrains

سال‌ها است که  IDEهای Jetbrains برای اینکه در سکوهای کاری متفاوت قابل اجرا باشند، با جاوا نوشته می‌شوند. برای مثال Rider که یک IDE مخصوص دات نت است نیز با جاوا نوشته شده‌است و مابقی آن‌ها نیز به همین صورت. اگر به مسیر C:\Program Files\JetBrains\JetBrains Rider 2018.3.4\bin\rider64.exe.vmoptions مراجعه کنید، فایل با پسوند vmoptions در حقیقت تنظیمات Java Virtual Machine یا JVM را به همراه دارد. این فایل طوری تنظیم شده‌است که کمترین منابع را مصرف کند؛ به همین جهت شاید در حین کار کردن با این IDEها احساس کنید که کند هستند. تنظیمات JVM مخصوص جاوای ویندوز و جاوای مک و لینوکس را در اینجا و اینجا می‌توانید مطالعه کنید.
اگر بر این اساس فایل rider64.exe.vmoptions را بخواهیم تکمیل کنیم، می‌توان به تنظیمات زیر رسید:

-Xms1024m
-Xmx3072m
-Xss64m
-XX:ReservedCodeCacheSize=512m
-XX:+UseCompressedOops
-XX:NewRatio=2
-Dfile.encoding=UTF-8
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=250
-XX:NewSize=512m
-XX:MaxNewSize=512m
-XX:PermSize=512m
-XX:MaxPermSize=1024m
-XX:+UseParNewGC
-XX:ParallelGCThreads=4
-XX:MaxTenuringThreshold=1
-XX:SurvivorRatio=8
-XX:+UseCodeCacheFlushing
-XX:+AggressiveOpts
-XX:+CMSClassUnloadingEnabled
-XX:+CMSIncrementalMode
-XX:+CMSIncrementalPacing
-XX:+CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=65
-XX:+CMSScavengeBeforeRemark
-XX:+UseCMSInitiatingOccupancyOnly
-XX:-TraceClassUnloading
-XX:+AlwaysPreTouch
-XX:+TieredCompilation
-XX:+DoEscapeAnalysis
-XX:+UnlockExperimentalVMOptions
-XX:LargePageSizeInBytes=256m
-XX:+DisableExplicitGC
-XX:+ExplicitGCInvokesConcurrent
-XX:+PrintGCDetails
-XX:+PrintFlagsFinal
-XX:+CMSPermGenSweepingEnabled
-XX:+UseAdaptiveGCBoundary
-XX:+UseSplitVerifier
-XX:CompileThreshold=10000
-XX:+OptimizeStringConcat
-XX:+UseStringCache
-XX:+UseFastAccessorMethods
-XX:+UnlockDiagnosticVMOptions
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Xverify:none
برای ویرایش فایل rider64.exe.vmoptions، چون در مسیر C:\Program Files قرار دارد، نیاز است برای مثال نوت‌پد یا هر ویرایشگر متنی دیگر را با دسترسی ادمین اجرا کنید تا بتوانید تغییرات انجام شده را ذخیره نمائید. برای مثال اگر از notepad++ استفاده کنید، خودش این مساله را تشخیص داده و درخواست اجرای با دسترسی ادمین را نمایش می‌دهد.

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

علاوه بر موارد فوق، فایل C:\Program Files\JetBrains\JetBrains Rider 2018.3.4\bin\idea.properties را نیز می‌توانید جهت اعمال تغییرات زیر ویرایش کنید:

idea.max.intellisense.filesize=3500
idea.cycle.buffer.size=2048
بهبود کارآیی IDEهای Jetbrains
مطالب
نمایش رکوردها به ترتیب اولویت به کمک jQuery UI sortable در ASP.NET MVC

همان طور که می‌دانید کاربرد پذیری در خیلی از پروژه‌ها حرف اول رو می‌زند و کاربر دوست دارد کارهایی که انجام می‌دهد خیلی راحت و با استفاده از موس باشد.یکی از کار هایی که در اکثر پروژه‌ها نیاز است ، چیدمان ترتیب رکورد‌ها است. ما می‌خواهیم در این پست ترتیبی اتخاذ کنیم که کاربر بتواند رکورد‌ها را به هر ترتیبی که دوست دارد نمایش دهد.

از توضیحاتی که قبلا  دادم مشخص است که این کار احتمالا در 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));
        }

این هم خروجی کار من:

این عکس مربوط به است به قسمت مدیریت پروژه شیرآلات مرجان خزر


مطالب
دانلود مجوز SSL یک سایت HTTPS
اگر به مرورگرها دقت کرده باشید، امکان نمایش SSL Server Certificate یک سایت استفاده کننده از پروتکل HTTPS را دارند. برای مثال در فایرفاکس اگر به خواص یک صفحه مراجعه کنیم، در برگه امنیت آن، امکان مشاهده جزئیات مجوز SSL سایت جاری فراهم است:



سؤال: چگونه می‌توان این مجوزها را با کدنویسی دریافت یا تعیین اعتبار کرد؟

قطعه کد زیر، نحوه دریافت مجوز SSL یک سایت را نمایش می‌دهد:
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;

namespace DownloadCerts
{
    class Program
    {
        static void Main(string[] args)
        {
            // صرفنظر از خطاهای احتمالی مجوز
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

            var url = "https://pdfreport.codeplex.com";
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = WebRequestMethods.Http.Head;
            using (var response = request.GetResponse())
            { /* در اینجا مجوز، در صورت وجود دریافت شده */  }

            if (request.ServicePoint.Certificate == null)
                return;

            // ذخیره سازی مجوز در فایل
            var cert = new X509Certificate2(request.ServicePoint.Certificate);
            Console.WriteLine("Expiration Date: {0}", cert.GetExpirationDateString());
            var data = cert.Export(X509ContentType.Cert);
            File.WriteAllBytes("site.cer", data);

            Process.Start(Environment.CurrentDirectory);
        }
    }
}
ممکن است مجوز یک سایت معتبر نباشد. کلاس WebRequest در حین مواجه شدن با یک چنین سایت‌هایی، یک WebException را صادر می‌کند. از این جهت که می‌خواهیم حتما این مجوز را دریافت کنیم، بنابراین در ابتدای کار، ServerCertificateValidation را غیرفعال می‌کنیم.
سپس یک درخواست ساده را به آدرس سرور مورد نظر ارسال می‌کنیم. پس از پایان درخواست، خاصیت request.ServicePoint.Certificate با مجوز SSL یک سایت مقدار دهی شده است. در ادامه نحوه ذخیره سازی این مجوز را با فرمت cer مشاهده می‌کنید.


مطالب
بار کردن ساعت و تاریخ فعلی سرور با JQuery Ajax
در این مطلب می‌خواهم شما را با نحوه بار گزاری ساعت و تاریخ سیستم سرور با استفاده از JQuery Ajax آشنا کنم.
در بعضی از سایتها با استفاده از جاوا اسکریپت تاریخ و ساعت جاری سیستم کلاینت به او نشان داه می‌شود.
این روش یک مزیت دارد: اول اینکه این کدها سمت کلاینت اجرا میشن و برای سرور بار اضافی ایجاد نمیکنن.
و یک عیب هم دارد: در صورتی که ساعت و تاریخ روی سیستم کلاینت تنظیم نباشد، همین ساعت و تاریخ نادرست برای او نمایش داده می‌شود. همین عیب می‌تواند باعث افت کیفیت وب سایت شود.

اما راهی هست که تاریخ و ساعت سیستم سرور برای کاربر نشان داده شود و آن هم استفاده از JQuery Ajax هست. به صورتی که هر ثانیه درخواستی برای یک handler فرستاده می‌شود و آن handler نیز ساعت و تاریخ روی سرور را باز می‌گرداند و این مقدار بازگشته شده را می‌توان در تگی از صفحه وب نمایش داد.

مثال: ابتدا یک صفحه aspx می‌سازیم و تگ زیر را در آن قرار می‌دهیم:
<p id="datetime"></p>
ساعت و تاریخ بار شده از سرور در این تگ باید نشان داده شود.

سپس کدهای اسکریپت زیر را می‌نویسیم:
var auto_referesh = setInterval
 (
     function()
    {
         $.post
         (
            "GetDateTime.ashx",
             function (result) 
            {
                $('#datetime').html(result);
            }
        );
     }, 1000
 );
با نوشتن این کدها هر ثانیه یک بار، بوسیله Ajax درخواستی برای یک handler به اسم GetDateTime.ashx فرستاده می‌شود. وظیفه این handler برگرداندن تاریخ و ساعت فعلی سیستم سرور است. بعد از دریافت مقدار این مقدار از این handler، آنرا در تگ با شناسه datetime قرار می‌دهیم.

کد استفاده شده در handler هم به این صورت است:
<%@ WebHandler Language="C#" Class="GetDateTime" %>

using System;
using System.Web;

public class GetDateTime : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Write(DateTime.Now.ToString());
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}
در انتها فایل ضمیمه این مثال را از این لینک دریافت کنید:
AjaxDateTime.zip

مطالب
سریع‌تر کردن عملیات دریافت‌ اطلاعات از وب، توسط یک برنامه ASP.Net

فرض کنید یک برنامه ASP.Net نوشته‌اید که کار آن نمایش یک سری فید از سایت‌های مختلف است یا دریافت وضعیت آب و هوا از یک وب سرویس و نمایش آن در سایت می‌باشد و امثال آن (استفاده از WebRequest ، WebClient ، XmlDom/Reader و ...).
اگر همین عملیات را یکبار با ASP.Net 1.1 و بار دیگر با ASP.Net 2.0 به بالا انجام دهید، متوجه تفاوت سرعت دریافت قابل تاملی خواهید شد (ASP.Net 2.0 به بعد حدودا تا 10 ثانیه کندتر عمل می‌کند). علت چیست؟
در دات نت 1.1 ، تنظیمات پروکسی پیش فرض در کتابخانه‌های مربوطه وجود نداشت و به نال تنظیم شده بود. در دات نت 2 به بعد این مورد به پروکسی پیش فرض سیستم، تنظیم شده است. پروکسی پیش فرض سیستم همان تنظیماتی است که در internet explorer صورت می‌گیرد.
کاربر پیش فرض ASP.Net (مثلا NETWORK SERVICE) دسترسی خواندن این اطلاعات را از رجیستری ویندوز ندارد. علت این وقفه هم همین مورد است! (حتی اگر برنامه ویندوزی شما هم دسترسی خواندن اطلاعات کلیدهای HKLM رجیستری ویندوز را نداشته باشد، باز هم این مساله رخ خواهد داد)
دات نت فریم ورک سعی می‌کند تا این تنظیمات را از رجیستری یا مکان‌های میسر دیگر بخواند و در آخر پس از شکست کلیه حالات مختلف، کلاینت را به صورت مستقیم متصل خواهد کرد.
خوشبختانه این عملکرد پیش فرض قابل تغییر است. تنها کافی است چند سطر زیر را به فایل config برنامه خود اضافه کنید:

<system.net>
<defaultProxy>
<proxy bypassonlocal="true" usesystemdefault="false" />
</defaultProxy>
</system.net>

با این‌کار تشخیص خودکار پروکسی سیستم غیرفعال شده و وقفه‌ی معرفی شده دیگر وجود نخواهد داشت.
راه دیگر انجام آن، نسبت دادن نال به خاصیت Proxy شیء HttpWebRequest است که همین اثر را خواهد داشت.

مطالب
آشنایی با Leaflet
مقدمه
سیستم‌های جغرافیایی و GIS اهمیت زیادی در زندگی روزمره‌ی ما دارند. GIS به نرم افزار یا سخت افزاری اطلاق می‌شود که کاربر را قادر می‌سازد تا به ذخیره، بازیابی و تجزیه و تحلیل داده‌های جغرافیایی (Spatial) بپردازد. یکی از پایه‌های نرم افزار‌های GIS، نقشه و نمایش اطلاعات بر روی نقشه می‌باشد. به طور حتم در وب سایت‌ها مشاهده کرده‌اید که آدرس یک شرکت بر روی نقشه نمایان می‌شود یا به عنوان مثالی دیگر سرویس دهنده‌های اینترنت از نقشه برای نمایش میزان و کیفیت آنتن دهی در محله‌های مختلف یک شهر استفاده می‌کنند.
برای نمایش نقشه در نرم افزار‌های تحت وب کتابخانه‌های JavaScript ایی زیادی وجود دارند. این مطلب به معرفی کتاب خانه‌ی کدباز و رایگان leaflet می‌پردازد. leaflet یک کتابخانه‌ی مدرن JavaScript برای کار با نقشه می‌باشد. از خصوصیات بارز این کتابخانه پشتیبانی بسیار خوب آن از موبایل و دستگاههای لمسی است. Leaflet تنها 33 کیلوبایت حجم دارد و ویژگی‌های آن اغلب نیازهای‌های توسعه دهندگان را برای پیاده سازی نرم افزار‌های مبتنی بر نقشه پوشش می‌دهد. از مزایای این کتابخانه می‌توان به مشارکت جامعه‌ی بزرگ توسعه دهندگان، سورس خوانا و تمیز، مستندات خوب و تعداد زیادی پلاگین برای آن اشاره کرد.

آماده سازی صفحه
برای استفاده از Leaflet ابتدا باید فایل Style و JavaScript کتابخانه را ارجاع داد:
 <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
 <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
سپس یک div با یک Id مشخص را به صفحه اضافه می‌کنیم. div مورد نظر باید از ارتفاع مشخصی برخوردار باشد که به سادگی با style زیر میسر می‌گردد:
#map { height: 600px; }
پس از انجام مقدمات اکنون می‌توان یک نقشه را با تنظیمات دلخواهی در div تعریف شده نمایش داد.

تنظیمات اولیه نقشه
با کد زیر ابتدا یک وهله از شیء map ایجاد می‌شود:
var map = L.map('map').setView([29.6760859,52.4950737], 13);
همانطور که مشاهده می‌شود شناسه‌ی div تعریف شده از طریق سازنده به map پاس داده شده است و سپس به کمک تابع setView به محل مختصات جغرافیایی مورد نظر با زوم پیشفرض 13 نمایش داده می‌شود. طراحی Leaflet به صورتی است که استفاده از متدهای زنجیروار (chainable) را میسر می‌سازد. به عنوان نمونه در کد بالا تابع setView یک شیء map را بر می‌گرداند و توسعه دهنده می‌تواند از توابع دیگر مقدار بازگشتی استفاده کند. این مورد از نظر طراحی شبیه به jQuery می‌باشد.
اگر Google Maps را مشاهده کنید، متوجه می‌شوید که یک نقشه، به صورت مستطیل مستطیل، بارگزاری می‌شود. به این مستطیل‌ها Tile گفته می‌شود. tile‌ها همان فایل‌های png هستند و درواقع به ازای زوم‌های مختلف در محل‌های مختلف، tile‌های متفاوتی با شناسه‌ی مشخصی وجود دارند. تصویر زیر نقشه‌ی Google می‌باشد؛ قبل از اینکه tile‌ها بارگزاری شوند. اگر با دقت نگاه کنید مستطیل‌های بزرگ و کوچکی را مشاهده می‌کنید که قسمت‌های مختلف یک نقشه یا همان تایل می‌باشند.

 پس برای نمایش یک نقشه نیاز است tile‌ها را از یک منبع، در اختیار نقشه قرار داد. این منبع می‌تواند یک وب سرویس باشد.
پس از تعریف اولیه، نیاز است یک Tile Layer ایجاد کرده و آن را به نقشه اضافه کرد:
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
var osm = new L.TileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib}).addTo(map);
در کد بالا ابتدا آدرس tile server تعریف شده است. در این مثال از سرویس OpenStreetMap برای تهیه‌ی Tile‌ها استفاده شده است. سپس لینک سرویس دهنده، به همراه  متن attribution(نوشته‌ای که در زیر نقشه قرار می‌گیرد)  به شیء TileLayer پاس داده شد و شیء ایجاد شده از طریق متد addTo به شیء map اضافه شده است.
نتیجه‌ی کار در مرورگر اینگونه خواهد بود:


Marker، دایره و چندضلعی

در کنار نمایش Tile‌ها می‌توان اشکال گرافیکی نیز به نقشه اضافه کرد؛ مثل مارکر(نقطه)، مستطیل، دایره و یا یک Popup. اضافه کردن یک Marker به سادگی، با کد زیر صورت می‌پذیرد:

var marker = L.marker([29.623116,52.497856]).addTo(map);

محل مورد نظر به شیء مارکر پاس داده شده و مقدار بازگشتی به map اضافه شده است.

نمایش چند ضلعی و دایره هم کار ساده ای است. برای دایره باید ابتدا مختصات مرکز دایره و شعاع به متر را به L.circle پاس داد:

var circle = L.circle([29.6308217,52.5048021], 500, {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5
}).addTo(map);

در کد بالا علاوه بر محل و اندازه دایره، رنگ محیط، رنگ داخل و شفافیت (opacity) نیز مشخص شده‌اند.

برای چند ضلعی‌ها می‌توان به این صورت عمل کرد:

var polygon = L.polygon([
[29.628453, 52.488838],
[29.637368, 52.493987],
[29.637168, 52.503987]
]).addTo(map);


کار کردن با Popup ها

از Popup می‌توان برای نمایش اطلاعات اضافه‌ای بر روی یک محل خاص یا یک عنوان به مانند Marker استفاده کرد. برای مثال می‌توان اطلاعاتی درباره‌ی محل یک Marker یا دایره نمایش داد. در هنگام ایجاد marker، دایره و چندضلعی مقادیر بازگشتی در متغیر‌های جدایی ذخیره شدند. اکنون می‌توان به آن اشیاء یک popup اضافه کرد:

marker.bindPopup("باغ عفیف آباد").openPopup();
circle.bindPopup("I am a circle.");
polygon.bindPopup("I am a polygon.");

به علت اینکه openPopup برای Marker صدا زده شده، به صورت پیشفرض popup را نمایش می‌دهد. اما برای بقیه، نمایش با کلیک خواهد بود. البته الزاما نیازی نیست که popup روی یک شیء نمایش داده شود، می‌توان popup‌های مستقلی نیز ایجاد کرد:

var popup = L.popup()
    .setLatLng([51.5, -0.09])
    .setContent("I am a standalone popup.")
    .openOn(map);