استاد گرامی پرسشی داشتم
ما در سازمانمان نرم افزاری داریم که کاربران آن در Active directory تعریف شده اند.
برنامه با وب سرویس در ارتباط است که در یک سروری قرار گرفته است که آن سرور با یک سرور دیگر از طریق کابل شبکه در ارتباط است.
سرور دوم سروری است که پایگاه داده روی آن قرار گرفته است.
با توجه به اینکه با WCF کاربر جاری برنامه را می توان به دست آورد؛ ما کاربر جاری را تا سطح سرور 1 می آوریم ولی برای ارسال آن به اس کیو ال دو راه حل داریم.
راهی که هم اکنون از آن استفاده می کنیم این است که Connection string مان تک کاربره است و دیگر اینکه هم اکنون که کاربر جاری را داریم همان را با Connection string به سمت SQL بفرستیم و که در نتیجه گزارش گیری و مانیتورینگ بسیار خوبی خواهیم داشت. ولی باید همه کاربران در SQL تعریف شوند چون سرور پایگاه داده به دومین متصل نیست.
به نظر شما در صورتی که سرورهای نسبتاً خوبی از لحاظ سخت افزاری داشته باشیم و کاربرانی در حدود 2000 نفر به طور کلی و 200 نفر همزمان داشته باشیم، Connection string تک کاربره بهتر است یا چند کاربره؟
با سپاس فراوان
بستهی نصب SQL Server CE 3.5 SP2 وجود دارد:
اما برای برنامههای جدیدتر نیاز به افزودن بستهی نصب دیتابیس SQL Server CE نسخه 4 است که با عدم وجود این بسته روبرو هستیم. در ادامه با نحوهی افزودن این بستهها آشنا خواهید شد.
اینگونه بستهها در کنار برنامهی ساخت نصاب و در پوشهی SetupPrerequisites نگهداری شده و با نوع *.prq ذخیره میشوند. این نوع فایلها از نوع xml هستند و در واقع یک نوع کار نگاشت را انجام میدهند. برای نمونه محتویات یکی از این فایلها را در زیر میبینید:
<?xml version="1.0" encoding="UTF-8"?> <SetupPrereq> <conditions> <condition Type="32" Comparison="2" Path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server Compact Edition\v3.5\ENU" FileName="DesktopRuntimeVersion" ReturnValue="3.5.8080.0"></condition> </conditions> <operatingsystemconditions> <operatingsystemcondition MajorVersion="5" MinorVersion="0" PlatformId="2" CSDVersion="" ServicePackMajorMin="3"></operatingsystemcondition> <operatingsystemcondition MajorVersion="5" MinorVersion="1" PlatformId="2" CSDVersion="" Bits="1" ProductType="1"></operatingsystemcondition> <operatingsystemcondition MajorVersion="6" MinorVersion="0" PlatformId="2" CSDVersion="" Bits="1"></operatingsystemcondition> <operatingsystemcondition MajorVersion="5" MinorVersion="2" PlatformId="2" CSDVersion="" Bits="1" ProductType="2|3"></operatingsystemcondition> <operatingsystemcondition MajorVersion="6" MinorVersion="1" PlatformId="2" CSDVersion="" Bits="1"></operatingsystemcondition> <operatingsystemcondition MajorVersion="6" MinorVersion="0" PlatformId="2" CSDVersion="" Bits="1" ProductType="2|3"></operatingsystemcondition> </operatingsystemconditions> <files> <file LocalFile="<ISProductFolder>\SetupPrerequisites\SQL CE 3.5\SSCERuntime_x86-ENU.msi" URL="http://go.microsoft.com/fwlink/?LinkId=166085&clcid=0x409" CheckSum="86AF6D36DFF214718DCD35D851249D3D" FileSize="0,3164160"></file> </files> <execute file="SSCERuntime_x86-ENU.msi" cmdline="/q /norestart" cmdlinesilent="/q /norestart" returncodetoreboot="1641,3010,4123" requiresmsiengine="1"></execute> <properties Id="{A7C4B3C0-F3A0-426A-A043-E13DBA123E52}" Description="This prerequisite installs the Microsoft SQL Server Compact 3.5 SP2." AltPrqURL="http://saturn.installshield.com/is/prerequisites/microsoft sql ce 3.5 sp2.prq"></properties> <behavior Reboot="2"></behavior> </SetupPrereq>
برای نسخه 32 بیتی(Microsoft SQL CE 4.0 x86.prq ):
<?xml version="1.0" encoding="UTF-8"?> <SetupPrereq> <conditions> <condition Type="32" Comparison="2" Path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server Compact Edition\v4.0\ENU" FileName="DesktopRuntimeVersion" ReturnValue="4.0.8482.1"></condition> </conditions> <operatingsystemconditions> <operatingsystemcondition CSDVersion="" Bits="1"></operatingsystemcondition> </operatingsystemconditions> <files> <file LocalFile=".\SSCERuntime_x86-ENU.exe" URL="http://download.microsoft.com/download/0/5/D/05DCCDB5-57E0-4314-A016-874F228A8FAD/SSCERuntime_x86-ENU.exe" CheckSum="0A55733CF406FBD05DFCFF5A27A0B4F7" FileSize="0,2379544"></file> </files> <execute file="SSCERuntime_x86-ENU.exe"></execute> <properties Id="{2754916B-119B-4428-9F94-DC9E45072CCC}"></properties> <behavior Failure="4" Reboot="2"></behavior> </SetupPrereq>
<?xml version="1.0" encoding="UTF-8"?> <SetupPrereq> <conditions> <condition Type="32" Comparison="2" Path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server Compact Edition\v4.0\ENU" FileName="DesktopRuntimeVersion" ReturnValue="4.0.8482.1"></condition> </conditions> <operatingsystemconditions> <operatingsystemcondition CSDVersion="" Bits="2"></operatingsystemcondition> </operatingsystemconditions> <files> <file LocalFile=".\SSCERuntime_x64-ENU.exe" URL="http://download.microsoft.com/download/0/5/D/05DCCDB5-57E0-4314-A016-874F228A8FAD/SSCERuntime_x64-ENU.exe" CheckSum="A417082ECAEDD95AFB41F73DC140C350" FileSize="0,2621240"></file> </files> <execute file="SSCERuntime_x64-ENU.exe"></execute> <properties Id="{7CB7BE3C-614A-403F-94D9-5652285A3EDF}"></properties> <behavior Failure="4" Reboot="2"></behavior> </SetupPrereq>
تبدیلگر ایران سیستم به یونیکد
ایجاد یک request bin جدید
برای مشاهدهی محتوای ارسالی توسط postman بدون برپایی وب سرویس خاصی، از سایت requestbin استفاده خواهیم کرد. در اینجا با کلیک بر روی دکمهی create a request bin، یک آدرس موقتی را مانند http://requestbin.fullcontact.com/1gdduy21 برای شما تولید میکند. میتوان انواع و اقسام درخواستها را به این آدرس ارسال کرد و سپس با ریفرش کردن آن در مرورگر، دقیقا محتوای ارسالی به سمت سرور را بررسی نمود.
برای مثال اگر همین آدرس را در postman وارد کرده و سپس بر روی دکمهی send آن کلیک کنیم، پس از ریفرش صفحه، چنین تصویری حاصل میشود:
Encoding کوئری استرینگها در postman
مثال زیر را درنظر بگیرید:
در اینجا با استفاده از گرید ساخت Query Params، دو کوئری استرینگ جدید را ایجاد کردهایم که در دومی، مقدار وارد شده، دارای فاصله است. اگر این درخواست را ارسال کنیم، مشاهده خواهیم کرد که مقدار ارسالی توسط آن encoded نیست:
برای رفع این مشکل میتوان بر روی تکستباکس ورود مقدار یک کلید، کلیک راست کرد و از منوی باز شده، گزینهی encode URI component را انتخاب نمود:
البته برای اینکه این گزینه درست عمل کند، نیاز است یکبار کل متن را انتخاب کرد و سپس بر روی آن کلیک راست نمود، تا انتخاب گزینهی encode URI component، به درستی اعمال شود:
امکان تعریف متغیرها در آدرسهای HTTP
Postman از امکان تعریف path variables پشتیبانی میکند. برای مثال مسیر api.example.com/users/5/contracts/2 را در نظر بگیرید که میتواند سبب نمایش اطلاعات قرارداد دوم کاربر پنجم شود. برای پویا کردن یک چنین آدرسی در postman میتوان از مسیری مانند api.example.com/users/:userid/contracts/:contractid استفاده کرد:
اگر به تصویر فوق دقت کنیم، متغیرهای شروع شدهی با :، در قسمت path variables ذکر شدهاند و به سادگی قابل تغییر و مقدار دهی میباشند (در گریدی همانند گرید کوئری استرینگها) که برای آزمایش دستی، بسیار مفید هستند.
امکان ارسال فایلها به سمت سرور
زمانیکه برای مثال، نوع درخواست به Post تغییر میکند، امکان تنظیم بدنهی آن نیز مسیر میشود. در این حالت اگر گزینهی form-data را انتخاب کنیم، با نزدیک کردن اشارهگر ماوس به هر ردیف جدید (پیش از ورود کلید آن ردیف)، میتوان نوع Text و یا File را انتخاب کرد:
در اینجا پس از انتخاب گزینهی File، میتوان علاوه بر تعیین کلید این ردیف، با استفاده از دکمهی select files، چندین فایل را نیز برای ارسال انتخاب کرد:
روش انتقال درخواستهای پیچیده به Postman
تا اینجا روش ساخت درخواستهای متداولی را بررسی کردیم که آنچنان پیچیده، طولانی و به همراه جزئیات زیادی (مانند کوکیها،انواع و اقسام هدرها و ...) نبودند. فرض کنید میخواهید درخواست ارسال یک امتیاز جدید را به مطلبی در سایت جاری، توسط Postman شبیه سازی کنیم. برای اینکار، توسط مرورگر کروم به سایت وارد شده و پس از لاگین و تنظیم خودکار کوکیهای اعتبارسنجی، برگهی developer tools مرورگر را باز کرده و در آن، قسمت network را انتخاب کنید:
در اینجا گزینهی preserve log را نیز انتخاب کنید تا پس از ارسال درخواستی، سابقهی عملیات، پاک نشود. سپس به صورت معمولی به مطلبی امتیاز دهید. اکنون بر روی مدخل درخواست آن کلیک راست کرده و از منوی ظاهر شده، گزینهی Copy->Copy as cURL را انتخاب کنید تا این عملیات و تمام جزئیات مرتبط با آنرا تبدیل به یک دستور cURL کرده و به حافظه کپی کند.
سپس در postman، از منوی بالای صفحه، سمت چپ آن، گزینهی Import را انتخاب کنید:
در ادامه این دستور کپی شدهی در حافظه را در قسمت Paste Raw Text، قرار دهید و بر روی دکمهی import کلیک کنید:
در این حالت postman این دستور را پردازش کرده و فیلدهای ساخت یک درخواست را به صورت خودکار پر میکند.
یک نکتهی مهم: در حالت انتخاب Copy->Copy as cURL در مرورگر کروم، دو گزینهی cmd و bash موجود هستند. حالت bash را باید انتخاب کنید تا توسط postman به دسترسی parse شود. حالت cmd یک چنین خروجی مشکل داری را در postman تولید میکند که قابل ارسال به سمت سرور نیست:
اما جزئیات حالت bash آن، به درستی parse شدهاست و قابلیت send مجدد را دارد:
کار با کوکیها در Postman
کوکیها نیز در اصل به صورت یک هدر HTTP به صورت خودکار توسط مرورگرها به سمت سرور ارسال میشوند؛ اما Postman روش سادهتری را برای تعریف و کار با آنها ارائه میدهد (و ترجیح میدهد که بین کوکیها و هدرها تفاوت قائل شود؛ هم در زمان ارسال و هم در زمان نمایش response که در کنار قسمت هدرهای دریافتی از سرور، لیست کوکیهای دریافتی نیز به صورت مجزایی نمایش داده میشوند).
با کلیک بر روی لینک Cookies، در ذیل قسمتی که آدرس یک درخواست تنظیم میشود، قسمت مدیریت کوکیها نیز ظاهر خواهد شد که با انتخاب هر نامی در اینجا، میتوان مقدار آنرا ویرایش و یا حتی حذف کرد. در این لیست، تمام کوکیهایی را که تاکنون تنظیم کرده باشید، میتوانید مشاهده کنید (و مختص به برگهی خاصی نیست) و همانند قسمت مدیریت کوکیهای یک مرورگر رفتار میکند.
روش کار با آن نیز به این صورت است: ابتدا باید یک دومین را اضافه کنید. سپس ذیل دومین اضافه شده، دکمهی Add cookie ظاهر میشود و به هر تعدادی که لازم باشد، میتوان برای آن دومین کوکی تعریف کرد:
پس از تعریف کوکیها، در حین کلیک بر روی دکمهی send، کوکیهای متعلق به دومین وارد شدهی در قسمت آدرس درخواست، از قسمت مدیریت کوکیها به صورت خودکار دریافت شده و به سمت سرور ارسال خواهند شد.
به اشتراک گذاری سابقهی درخواستها
در قسمت اول مشاهده کردیم که برای ذخیره سازی درخواستها، باید آنها را در مجموعههای Postman، ذخیره و ساماندهی کرد. برای گرفتن خروجی از این مجموعهها و به اشتراک گذاشتن آنها، اگر اشارهگر ماوس را بر روی نام یک مجموعه حرکت دهیم، یک دکمهی جدید با برچسب ... ظاهر میشود:
با کلیک بر روی آن، یکی از گزینههای آن، export نام دارد که جزئیات تمام درخواستهای یک مجموعه را به صورت یک فایل JSON ذخیره میکند. برای نمونه فایل JSON خروجی دو قسمت قبل این سری را میتوانید از اینجا دریافت کنید: httpbin.postman_collection.json
پس از تولید این فایل JSON، برای بازیابی آن میتوان از دکمهی Import که در منوی سمت چپ، بالای postman قرار دارد، استفاده کرد که نمونهای از آنرا برای Import جزئیات درخواستهای cURL پیشتر مشاهده کردید. در اینجا، همان اولین گزینهی دیالوگ Import که Import file نام دارد، دقیقا برای همین منظور تدارک دیده شدهاست.
توسعه سیستم مدیریت محتوای DNTCms - قسمت اول
"(مثلا به محض ثبت شدن منوهایش به صفحه اصلی افزوده شود) نیاز به جدوالی برای ثبت و مدیریت آنها میباشد"
Ajax.BeginForm و ارسال فایل به سرور در ASP.NET MVC
فعال سازی و پردازش صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid در ASP.NET MVC
فرمت کردن اطلاعات نمایش داده شده به کمک jqGrid در ASP.NET MVC
استفاده ازExpressionها جهت ایجاد Strongly typed view در ASP.NET MVC
فرمهای پویای jqGrid نیز به صورت Ajax ایی به سرور ارسال میشوند و اگر نوع عناصر تشکیل دهندهی آنها file تعیین شوند، قادر به ارسال این فایلها به سرور نخواهند بود. در ادامه نحوهی یکپارچه سازی افزونهی AjaxFileUpload را با فرمهای jqGrid بررسی خواهیم کرد.
تغییرات فایل Layout برنامه
در اینجا دو فایل جدید ajaxfileupload.js و jquery.blockUI.js به مجموعهی فایلهای تعریف شده اضافه شدهاند:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> <link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" /> <link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" /> <link href="~/Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div> @RenderBody() </div> <script src="~/Scripts/jquery-1.7.2.min.js"></script> <script src="~/Scripts/jquery-ui-1.8.11.min.js"></script> <script src="~/Scripts/i18n/grid.locale-fa.js"></script> <script src="~/Scripts/jquery.jqGrid.src.js"></script> <script src="~/Scripts/ajaxfileupload.js"></script> <script src="~/Scripts/jquery.blockUI.js"></script> @RenderSection("Scripts", required: false) </body> </html>
PM> Install-Package jQuery.BlockUI
نکتهای در مورد واکنشگرا کردن jqGrid
اگر میخواهید عرض jqGrid به تغییرات اندازهی مرورگر پاسخ دهد، تنها کافی است تغییرات ذیل را اعمال کنید:
<div dir="rtl" id="grid1" style="width:100%;" align="center"> <div id="rsperror"></div> <table id="list" cellpadding="0" cellspacing="0"></table> <div id="pager" style="text-align:center;"></div> </div> <script type="text/javascript"> $(document).ready(function () { // Responsive jqGrid $(window).bind('resize', function () { var targetContainer = "#grid1"; var targetGrid = "#list"; $(targetGrid).setGridWidth($(targetContainer).width() - 2, true); }).trigger('resize'); $('#list').jqGrid({ caption: "آزمایش هفتم", /// ..... }).navGrid( /// ..... ).jqGrid('gridResize', { minWidth: 400, minHeight: 150 }); }); </script>
همچنین اگر میخواهید کاربر بتواند اندازهی گرید را دستی تغییر دهد، به انتهای تعاریف گرید، تعریف متد gridResize را نیز اضافه کنید.
نحوهی تعریف ستونی که قرار است فایل آپلود کند
colModel: [ { name: '@(StronglyTyped.PropertyName<Product>(x=>x.ImageName))', index: '@(StronglyTyped.PropertyName<Product>(x => x.ImageName))', align: 'center', width: 220, editable: true, edittype: 'file', formatter: function (cellvalue, options, rowObject) { return "<img src='/images/" + cellvalue + "?rnd=" + new Date().getTime() + "' />"; }, unformat: function (cellvalue, options, cell) { return $('img', cell).attr('src').replace('/images/', ''); } } ],
Rnd اضافه شده به انتهای آدرس تصویر، جهت جلوگیری از کش شدن آن تعریف شدهاست.
کتابخانهی JqGridHelper
در قسمتهای قبل مطالب بررسی jqGrid یک سری کلاس مانند JqGridData برای بازگشت اطلاعات مخصوص jqGrid و یا JqGridRequest برای دریافت پارامترهای ارسالی توسط آن به سرور، تهیه کردیم؛ به همراه کلاسهایی مانند جستجو و مرتب سازی پویای اطلاعات.
اگر این کلاسها را از پروژهها و مثالهای ارائه شده خارج کنیم، میتوان به کتابخانهی JqGridHelper رسید که فایلهای آن در پروژهی پیوست موجود هستند.
همچنین در این پروژه، کلاسی به نام StronglyTyped با متد PropertyName جهت دریافت نام رشتهای یک خاصیت تعریف شدهاست. گاهی از اوقات این تنها چیزی است که کدهای سمت کلاینت، جهت سازگار شدن با Refactoring و Strongly typed تعریف شدن نیاز دارند و نه ... محصور کنندههایی طویل و عریض که هیچگاه نمیتوانند تمام قابلیتهای یک کتابخانهی غنی جاوا اسکریپتی را به همراه داشته باشند.
با کمی جستجو، برای jqGrid نیز میتوانید از این دست محصور کنندههارا پیدا کنید اما ... هیچکدام کامل نیستند و دست آخر مجبور خواهید شد در بسیاری از موارد مستقیما JavaScript نویسی کنید.
یکپارچه سازی افزونهی AjaxFileUpload با فرمهای jqGrid
پس از این مقدمات، ستون ویژهی actions که inline edit را فعال میکند، چنین تعریفی را پیدا خواهد کرد:
colModel: [ { name: 'myac', width: 80, fixed: true, sortable: false, resize: false, formatter: 'actions', formatoptions: { keys: true, afterSave: function (rowid, response) { doInlineUpload(response, rowid); }, delbutton: true, delOptions: { url: "@Url.Action("DeleteProduct","Home")" } } } ],
و ویژگیهای قسمتهای edit، add و delete فرمهای پویای jqGrid باید به نحو ذیل تغییر کنند:
$('#list').jqGrid({ caption: "آزمایش هفتم", // .... }).navGrid( '#pager', //enabling buttons { add: true, del: true, edit: true, search: false }, //edit option { width: 'auto', reloadAfterSubmit: true, checkOnUpdate: true, checkOnSubmit: true, beforeShowForm: function (form) { centerDialog(form, $('#list')); }, afterSubmit: doFormUpload, closeAfterEdit: true }, //add options { width: 'auto', url: '@Url.Action("AddProduct","Home")', reloadAfterSubmit: true, checkOnUpdate: true, checkOnSubmit: true, beforeShowForm: function (form) { centerDialog(form, $('#list')); }, afterSubmit: doFormUpload, closeAfterAdd: true }, //delete options { url: '@Url.Action("DeleteProduct","Home")', reloadAfterSubmit: true }).jqGrid('gridResize', { minWidth: 400, minHeight: 150 });
افزونهی AjaxFileUpload پس از ارسال اطلاعات عناصر غیر فایلی فرم، باید فعال شود. به همین جهت است که از رویداد afterSubmit در حالت نمایش فرمهای پویا و رویداد afterSave در حالت ویرایش inline استفاده کردهایم.
در ادامه تعاریف متدهای doInlineUpload و doUpload بکار گرفته شده در رویداد afterSubmit را مشاهده میکنید:
function doInlineUpload(response, rowId) { return doUpload(response, null, rowId); } function doFormUpload(response, postdata) { return doUpload(response, postdata, null); } function doUpload(response, postdata, rowId) { // دریافت خروجی متد ثبت اطلاعات از سرور // و استفاده از آی دی رکورد ثبت شده برای انتساب فایل آپلودی به آن رکورد var result = $.parseJSON(response.responseText); if (result.success === false) return [false, "عملیات ثبت موفقیت آمیز نبود", result.id]; var fileElementId = '@(StronglyTyped.PropertyName<Product>(x=>x.ImageName))'; if (rowId) { fileElementId = rowId + "_" + fileElementId; } var val = $("#" + fileElementId).val(); if (val == '' || val === undefined) { // فایلی انتخاب نشده return [false, "لطفا فایلی را انتخاب کنید", result.id]; } $('#grid1').block({ message: '<h4>در حال ارسال فایل به سرور</h4>' }); $.ajaxFileUpload({ url: "@Url.Action("UploadFiles", "Home")", // مسیری که باید فایل به آن ارسال شود secureuri: false, fileElementId: fileElementId, // آی دی المان ورودی فایل dataType: 'json', data: { id: result.id }, // اطلاعات اضافی در صورت نیاز complete: function () { $('#grid1').unblock(); }, success: function (data, status) { $("#list").trigger("reloadGrid"); }, error: function (data, status, e) { alert(e); } }); return [true, "با تشکر!", result.id]; }
متد doUpload توسط پارامتر response، اطلاعات بازگشتی پس از ذخیره سازی متداول اطلاعات فرم را دریافت میکند. برای مثال ابتدا اطلاعات معمولی یک محصول در بانک اطلاعاتی ذخیره شده و سپس id آن به همراه یک خاصیت به نام success از طرف سرور بازگشت داده میشوند.
اگر success مساوی true بود، ادامهی کار آپلود فایل انجام خواهد شد. در اینجا ابتدا بررسی میشود که آیا فایلی از طرف کاربر انتخاب شدهاست یا خیر؟ اگر خیر، یک پیام اعتبارسنجی سفارشی به او نمایش داده خواهد شد.
خروجی متد doUpload حتما باید به شکل یک آرایه سه عضوی باشد. عضو اول آن true و false است؛ به معنای موفقیت یا عدم موفقیت عملیات. عضو دوم پیام اعتبارسنجی سفارشی است و عضو سوم، Id ردیف.
در ادامه افزونهی jQuery.BlockUI فعال میشود تا ارسال فایل به سرور را به کاربر گوشزد کند.
سپس فراخوانی متداول افزونهی ajaxFileUpload را مشاهده میکنید. تنها نکتهی مهم آن فراخوانی متد reloadGrid در حالت success است. به این ترتیب گرید را وادار میکنیم تا اطلاعات ذخیره شده در سمت سرور را دریافت کرده و سپس تصویر را به نحو صحیحی نمایش دهد.
کدهای سمت سرور آپلود فایل
[HttpPost] public ActionResult AddProduct(Product postData) { // ... return Json(new { id = postData.Id, success = true }, JsonRequestBehavior.AllowGet); } [HttpPost] public ActionResult EditProduct(Product postData) { // ... return Json(new { id = postData.Id, success = true }, JsonRequestBehavior.AllowGet); } // todo: change `imageName` according to the form's file element name [HttpPost] public ActionResult UploadFiles(HttpPostedFileBase imageName, int id) { // .... return Json(new { FileName = product.ImageName }, "text/html", JsonRequestBehavior.AllowGet); }
در حالتهای Add و Edit، نیاز است id رکورد ثبت شده بازگشت داده شود. این id در سمت کلاینت توسط پارامتر response دریافت میشود. از آن در افزونهی ارسال فایل به سرور استفاده خواهیم کرد. اگر به متد UploadFiles دقت کنید، این id را دریافت میکند. بنابراین میتوان یک ربط منطقی را بین فایل ارسالی و رکورد متناظر با آن برقرار کرد.
Content type مقدار بازگشتی از متد UploadFiles حتما باید text/html باشد (افزونهی ارسال فایلها، اینگونه کار میکند).
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید:
jqGrid07.zip
در این قسمت در ابتدا نحوهی باز کردن یک پایگاه داهی چند بعدی را در محیط BIMS بررسی کرده و سپس چگونگی ساخت یک MDB را از پایه بررسی میکنیم. برای ادامه دادن این قسمت نیاز میباشد که پایگاه دادهی AdventureWorkDW2008 را در SSAS نصب کرده باشید .
در ابتدا مطابق شکل زیر منوی File سپس زیر منوی Open و Analysis Service Database را انتخاب نمایید.
در ادامه میبایست نام Server را مشخص نمایید و دقت داشته باشید که در اینجا منظور از نام سرور، نام سرور SSAS میباشد (در صورتیکه بر روی خود سرور در حال کار میباشید از . به جای نام سرور استفاده کنید). سپس در قسمت Database، نام پایگاه دادهی چند بعدی را انتخاب نمایید. در صورتی که به جز Adventure Work DW 2008 ، پایگاه دادههای چند بعدی دیگری را در SSAS داشته باشید، یک لیست از آنها را مشاهده خواهید کرد و در صورتیکه لیست شما خالی میباشد، احتمال دارد نام سرور اشتباه باشد یا روی سرویس SSAS مربوط به آن سرور هیچ پایگاه دادهی چند بعدی نصب نباشد.
حال مسیری را برای ذخیره سازی پروژهی جدید در نظر بگیرید:
پس از کمی شکیبایی، واکشی اطلاعات از روی پایگاه دادهی چند بعدی انتخاب شده انجام میشود و یک پروژه در ارتباط با آن پایگاه داده ساخته میشود.
همان طور که مشخص میباشد، یک شیء درون شاخهی Data Source وجود دارد که مشخص کنندهی ارتباط این پروژه با پایگاه دادهی Data Warehouse است. برای مشاهدهی این ارتباط، بر روی Adventure Work DW کلیک راست کنید و سپس گزینهی Open را انتخاب نمایید. در ادامه گزینهی Edit را بزنید.
سپس در پنجرهی جدید، تنظیمات رشتهی ارتباطی با DW را مشاهده نمایید
با زدن کلید Test Connection باید پیام Test Connection Succeeded را مشاهده نمایید. اکنون پنجرهها را با زدن کلید OK ببندید.
در قسمت Data Source View سه شی تعریف شده است؛ براساس دسته بندی مورد نظر و جاری در Business موجود در Adventure Work .
با کلیک راست کردن بر روی Adventure Works DW و انتخاب گزینهی Open، اقدام به باز کردن DSV انتخاب شده کنید. در صفحهی باز شده میتوانید انواع دیاگرام تهیه شده را مشاهده نمایید و همچنین لیستی از جداول موجود در این DSV مشخص میباشد.
با کلیک راست کردن در فضای خالی دیاگرام ، امکان Add/Remove کردن جداول را به دیاگرام دارید.
در شکل بالا بعد از انتخاب یک جدول در سمت راست و انتقال آن به سمت چپ میتوانید با زدن دکمهی Add Related Table براساس کلیدهای خارجی، جداول مرتبط با جدول انتخاب شده را به صورت خودکار انتخاب نمایید و به قسمت چپ انتقال دهید.
شما در ساخت Cube مشخص مینمایید که Cube را از کدام DSV خواهید ساخت. بنابراین انتخاب جداول در DSV ها میبایست براساس نوع Business شما باشد تا در ساخت Cube به مشکلی برخورد نکنید.
در ساختار درختی موجود در پنجرهی Solution در شاخهی Cube، میتوانید Adventure Works را باز کنید (کلیک راست و انتخاب Open ) .
در شکل بالا در سمت چپ، میتوانید Measure ها و Dimension های موجود در این Cube را مشاهده کنید. همچنین در قسمت بالا چندین Tab وجود دارند که در هر کدام تنظیمات بیشتری را بر روی Cube اعمال میکنیم. با توجه به اینکه طراحی Cube ها کاری تخصصی میباشد و نیاز به اطلاعات زیادی دارد اجازه دهید مقاله ای در خصوص طراحی Cube در SSAS جداگانه انتشار داده شود و فعلا در همین حد بسنده کنیم. با این حال در صورت نیاز میتوانید برای اطلاعات بیشتر در این خصوص کتاب Microsoft SQL Server Analysis Services 2008 With MDX از انتشارات Wrox را مطالعه نمایید.
در Solution Explorer در شاخهی ،Dimensions میتوانید تمامی بعدهایی که در تمامی Cube های شما استفاده شدهاند را مشاهده نمایید.
با انتخاب یک بعد (ترجیحا بعد Date ) و با کلیک راست کردن و انتخاب گزینهی Open آن را باز نمایید.
در پنجرهی باز شده میتوانید 4 Tab در بالا را مشاهد نمایید و در Tab نخست، Attribute ها و همچنین ساختار Hierarchies و در آخر Data source View را مشاهده نمایید.
در Attribute relationships می توانید ارتباط صفتهای یک بعد را مشخص نمایید.
در Browsing Tab میتوانید محتوای Dimension را بررسی نمایید (البته اگر در پروژهی جدید قرار دارید حتما میبایست پروژه را Deploy کرده باشید. در حالتیکه یک پایگاه داهی چند بعدی را باز میکنید، نیازی به Deploy کردن نمیباشد؛ زیرا حتما قبلا این کار انجام شده است (زیرا شما پایگاه دادهی چند بعدی را بعد از Deploy کردن پروژهی SSAS خواهید داشت ))
در صورتیکه مانند روش بالا یک پایگاه دادهی چند بعدی را باز کنیم، دیگر نیازی به Deploy کردن نمیباشد و فقط برای اعمال تغییرات روی پایگاه دادهی چند بعدی باید پروژه را Process کنیم و برای این منظور روی نام پروژه کلیک راست کرده و گزینهی Process را انتخاب کنید. با این کار تغییرات اعمال شده در BIMS روی پایگاه دادهی SSAS اعمال میگردند و دادهها با توجه به ساختار Cube ها دوباره پردازش میشوند.
برای ساخت یک پروژهی جدید به شکل زیر عمل میکنیم :
در ابتدا BIMS را باز کرده و سپس به منوی File رفته و در قسمت New گزینهی Project را انتخاب میکنیم. سپس در صفحهی باز شده، مطابق شکل زیر عمل کرده و یک پروژه از نوع Analysis Service Multidimensional … میسازیم.
سپس برروی شاخهی Data Source کلیک راست کرده و گزینهی New Data Source را میزنیم و پنجرههای ویزارد را به جلو میرویم.
در ابتدا باید یک Connection به DW تولید کنیم. برای این منظور در پنجرهی فوق دکمهی New را زده و اطلاعات را مطابق شکل زیر پر میکنیم.
و سپس OK را میزنیم.
در صورتی که SSAS در یک سرور دیگر نصب شده است در پنجرهی بعدی نیاز میباشد نام کاربری را که به سرویس SSAS در آن سرور دسترسی دارد را وارد کنیم.
در صورتی که SSAS روی سیستم Local نصب شده است و کاربری که با آن Login هستیم دسترسی کافی به SSAS را دارد، گزینهی Use the credentials of the current user را انتخاب میکنیم.
در صفحهی آخر یک نام برای DS انتخاب میکنیم.
سپس نیاز میباشد یک DSV بسازیم. برای این منظور روی شاخهی Data Source View کلیک راست کرده و گزینهی New را انتخاب کرده و سپس در پنجرهی Wizard باید Data Source ساخته شده در مرحلهی قبل را انتخاب کرده و سپس Next را بزنیم. در اینجا بر اساس بیزینسهای مختلف، راه کارهای گوناگونی را داریم. به عبارت دیگر میتوان جداول Fact و Dimension های مرتبط با آنرا بر اساس زیر سیستمهای مختلف انتخاب کرده و برای هر کدام از آنها یک DSV بسازیم. به نظر من میتوانیم تمامی جداول را در این مرحله انتخاب کرده و سپس این تفکیک بندی را در سطح Cube ها انجام داد. به طور کلی دقت داشته باشید به هیچ عنوان DSV و Cube های سیستم را خیلی تفکیک نکنید. زیرا در نوشتن کوئریها و Join بین Cube ها با مشکل و سختی روبرو خواهید شد. (از لحاظ تجربی تفکیک بندی به شرطی صورت گیرد که نیازی به Join کردن Cube ها در MDX Query ها نباشد.)
سپس یک نام برای DSV خود انتخاب کرده و Finish را بزنید.
خوب؛ آخرین مرحله ساخت Cube میباشد (البته در طراحی Cube مطالب بسیاری وجود دارند که در یک مقالهی دیگر تلاش خواهم کرد تمامی آن موارد را توضیح دهم.)
برای ساخت Cube ، روی شاخهی Cube کلیک راست کرده و گزینهی New را بزنید.
سپس Use Existing Table را انتخاب کرده و Next را بزنید.
در پنجرهی بعدی باید DSV را انتخاب کرد و بعد جداول مورد نیاز در طراحی Cube را انتخاب کنید. فراموش نکنید در صورت انتخاب یک Fact تمامی Dimension های مرتبط با آن را انتخاب نماید. دکمه Next را بزنید.
در پنجرهی بعدی باید جداول Fact را انتخاب کرده و دکمهی Next را بزنید.
سپس در پنجرهی بعدی دایمنشن را انتخاب نمایید. (ترجیحا اجازه بدهید خود BIMS برای شما Dimension ها را بسازد، هرچند که خود شما میتوانید بعدا به صورت دستی Dimension ها را ایجاد کنید).
بعد از زدن دکمهی Next نامی برای Cube خود انتخاب نمایید و سپس دکمهی Finish را بزنید.
بعد از ساخت Cube ، چندین دایمنشن به صورت خودکار ساخته میشوند . البته گاهی نیاز میباشد که اقدام به ساخت ساختارهای سلسله مراتبی در Dimension ها کنیم (این مورد را در یک مقاله جداگانه آموزش خواهم داد.)
پروژه با کلیدهای ترکیبی Ctrl+Shift+B ساخته میشود و بعد از اطمینان از درست بودن ساخت پروژه، آن را باید Deploy کرد.
برای Deploy کردن یک پروژه کافی است بعد از تنظیم کردن رشتهی ارتباطی در DS (قبلا توضیح داده شده است) روی پروژه کلیک راست کرده و گزینهی Deploy را بزنیم.