{"error":{"code":"UnsupportedApiVersion","message":"The HTTP resource that matches the request URI 'http://localhost:45225/api/account/login?ReturnUrl=%2Fidentity%2Fhome' does not support HTTP method 'GET'."}}
با سلام. من در پروژه DNTIdentity برای تنظیمات لاگین کاربران غیر وبی طبق پروژه اعتبارسنجی مبتنی بر کوکیها در ASP.NET Core 2.0 بدون استفاده از سیستم Identity تنظیمات انجام دادم. و لاگین به درستی انجام میگیرد ولی مشکل اینجاس که اگه بخوام توی سایت به صورت پیش فرض لاگین کنم خطای زیر را میدهد. یعنی میخواد با خود اون لاگینی که برای کاربران غیر وبی ساختم وارد بشود. میخواستم بدونم آیا میشود تنظیم کرد که برای ورود کاربران غیر وبی با api/account و برای خود سایت با account ای در خود پروژه پیاده سازی شده است وارد شوند
در قسمت قبل با مفهوم مایکرو سرویسها آشنا شدیم. سرویسهای کوچک و مجزایی که بصورت مستقل، قابلیت توسعه و استقرار دارند و در راستای انجام یک قابلیت کسب و کار در اختیار دیگران قرار میگیرند.
برای روشن شدن موضوع فرض کنید میخواهیم در بخشی از سیستم، performance را افزایش دهیم. برای این امر میتوانیم از هر تکنولوژی که به ما کمک میکند، استفاده کنیم. برای نمونه در یک سیستم شبکه اجتماعی، میتوانیم اطلاعات مربوط به کاربران و ارتباطات آنها را در یک دیتابیس مبتنی بر گراف و اطلاعات مربوط به پستها و نظرات کاربران را در یک دیتابیس سندگرا ذخیره کنیم. به این ترتیب مشاهده میکنیم که وابستهی به تکنولوژی خاصی نمیباشیم و میتوانیم بر اساس نیاز خود، از تکنولوژی مورد نظر بهره ببریم.
مایکرو سرویسها به ما این اجازه را میدهند تا در انتخاب تکنولوژیها نهایت دقت را انجام دهیم و متوجه شویم که تکنولوژیهای جدید چگونه میتوانند به ما کمک کنند.
یکی از بزرگترین موانع در استفاده و انتخاب یک تکنولوژی جدید، ایجاد وابستگی سیستم به آن میباشد. در یک سیستم یکپارچه چنانچه قصد تغییر زبان مورد استفاده یا دیتابیس یا فریمورک مورد استفاده را داشته باشیم، سیستم هزینهی سنگینی را متحمل میشود. در حالیکه در مایکرو سرویسها میتوانیم این تغییرات را با کمترین هزینه انجام دهیم. البته باید توجه داشت که استفاده از تکنولوژی جدید چالشها و سربارهای خودش را دارد و انتخاب یک تکنولوژی جدید نیازمند بررسی کارشناسانه و دقیق میباشد.
Organizational Alignment
ویژگیهای یک مایکرو سرویس چیست؟
بعد از آشنایی با معماری مایکرو سرویسها میخواهیم با ویژگیهای آن آشنا شویم. البته باید به این نکته توجه داشت که همهی معماریهای مایکروسرویسها این ویژگیها را ندارند؛ ولی میتوان انتظار داشت اکثر آنها این ویژگیها را از خود به نمایش بگذارند.
Componentization via Services
تعریف ما از component، واحدی از نرم افزار میباشد که به تنهایی قابل جایگزینی و بهروز رسانی میباشد.
همانطور که گفته شد، مایکرو سرویسها یک نرم افزار را به سرویسهای (business component) کوچکتری تقسیم میکنند که به تنهایی قابل توسعه و استقرار میباشند. ما کتابخانهها را به عنوان component در نظر میگیریم که به نرم افزار ما پیوند خوردهاند و به وسیله فراخوانی توابع در پروسه نرم افزار قابل استفاده میباشند. در حالیکه سرویسها componentهایی هستند که خارج از پروسه نرم افزار ما میباشند و به وسیله مکانیزمهای ارتباطی مانند Web Service Request و Remote Procedure Call قابل دسترسی هستند.
در سیستم های یکپارچه که از چندین component تشکیل شدهاند و این componentها در جریان یک پروسه با هم در ارتباط هستند، اگر بخواهیم در یک component تغییر ایجاد کنیم، این تغییر نیازمند استقرار مجدد کل سیستم میباشد. در حالیکه در معماری مایکرسرویس، کافی است شما component (سرویس) ای را که تغییر کردهاست، دوباره مستقر کنید و سایر بخشهای سیستم از این تغییر تاثیر نمیپذیرند.
Technology Heterogeneity
یک سیستم را در نظر بگیرید که از همکاری چندین سرویس تشکیل شدهاست. ما میتوانیم تصمیم بگیریم که برای هر کدام از سرویسها از تکنولوژی متفاوتی استفاده کنیم. این امر به ما اجازه میدهد برای حل هر مشکل، از بهترین ابزار و تکنولوژی استفاده کنیم. این امر بر خلاف سیستمهایی که تنها باید از تکنولوژی بکار رفته در سیستم استفاده کنند، انعطاف پذیری سیستم را بسیار بالا میبرد.برای روشن شدن موضوع فرض کنید میخواهیم در بخشی از سیستم، performance را افزایش دهیم. برای این امر میتوانیم از هر تکنولوژی که به ما کمک میکند، استفاده کنیم. برای نمونه در یک سیستم شبکه اجتماعی، میتوانیم اطلاعات مربوط به کاربران و ارتباطات آنها را در یک دیتابیس مبتنی بر گراف و اطلاعات مربوط به پستها و نظرات کاربران را در یک دیتابیس سندگرا ذخیره کنیم. به این ترتیب مشاهده میکنیم که وابستهی به تکنولوژی خاصی نمیباشیم و میتوانیم بر اساس نیاز خود، از تکنولوژی مورد نظر بهره ببریم.
مایکرو سرویسها به ما این اجازه را میدهند تا در انتخاب تکنولوژیها نهایت دقت را انجام دهیم و متوجه شویم که تکنولوژیهای جدید چگونه میتوانند به ما کمک کنند.
یکی از بزرگترین موانع در استفاده و انتخاب یک تکنولوژی جدید، ایجاد وابستگی سیستم به آن میباشد. در یک سیستم یکپارچه چنانچه قصد تغییر زبان مورد استفاده یا دیتابیس یا فریمورک مورد استفاده را داشته باشیم، سیستم هزینهی سنگینی را متحمل میشود. در حالیکه در مایکرو سرویسها میتوانیم این تغییرات را با کمترین هزینه انجام دهیم. البته باید توجه داشت که استفاده از تکنولوژی جدید چالشها و سربارهای خودش را دارد و انتخاب یک تکنولوژی جدید نیازمند بررسی کارشناسانه و دقیق میباشد.
Resilience
چنانچه یکی ازسرویسها دچار اشکال شود و این مسئله بصورت زنجیروار برای تمام سرویسها رخ ندهد، با جدا شدن آن سرویس، درروند کار سیستم خللی بوجود نمیآید و سیستم بدون کمترین مشکلی به ادامه کار خود میپردازد. یعنی محدوده یک سرویس، دیوار حائلی میشود تا سایر بخشها تاثیر نپذیرند. در سیستمهای یکپارچه چنانچه یک سرویس دچار اشکال شود، سایر بخشهای سیستم نیز غیر قابل استفاده میشوند. البته میتوان با نصب نسخههای متفاوتی بر روی ماشینهای متفاوت (Scale out)، تاثیر اینگونه اختلالات را تا حدودی کاهش داد. اما بوسیله مایکرو سرویسها میتوانیم سیستمهایی را بسازیم که قادرند با خطاهای بوجود آمده در سرویسها بهدرستی رفتار کنند؛ تا خللی در کار سیستم ایجاد نشود.Scaling
فرض کنید در بخشی ازیک سیستم، دغدغه Performance بوجود میآید. چنانچه ما یک معماری یکپارچه را داشته باشیم، مجبوریم کل آن را scale کنیم. درحالیکه این مشکل تنها در بخش کوچکی از نرم افزار ایجاد شدهاست. اما اگرمعماری ما مایکرو سرویس باشد، فقط همان سرویس مربوطه را که بر روی آن دغدغه داریم، scale میکنیم و سایر بخشهای نرم افزار بدون نیاز به تغییر و بزرگ شدن، به کار خود ادامه میدهند.
Gilt یک خرده فروش آنلاین در صنعت مد میباشد که بخاطر مسائل Performance به معماری مایکروسرویسها روی آورد. آنها در سال 2007 با یک نرم افزار یکپارچه شروع به کار کردند. اما بعد از دوسال سیستم آنها قادر به مقابله با ترافیک سایت نبود. آنها با تقسیم بندی قسمتهای اصلی سیستم خود به مایکرو سرویسها، توانستند خیلی بهتر و موثرتر با ترافیک رسیده مقابله کنند و قابلیت دسترسی پذیری سیستم را افزایش دهند. در حال حاضر سیستم آنها از حدود 450 مایکرو سرویس تشکیل شده که هر کدام روی چندین ماشین مختلف در حال اجرا میباشند.
Ease of Deployment
تغییر حتی یک خط کد، در برنامهای که از چندین میلیون خط تشکیل شده است، ما را ملزم به استقرار مجدد کل سیستم و انتشار نسخه جدید میکند. این استقرار میتواند تاثیر و ریسک بالایی را داشته باشد و ما را مجبور به تغییرات بیشتر و انتشار نسخههای دیگر کند که این حجم زیاد تغییرات ممکن است به محصول ما ضربه بزند.
اما در مایکرو سرویسها یک تغییر کوچک، تمام سیستم را تحت تاثیر قرار نمیدهد. بلکه تنها تغییرات مربوط به سرویس مورد نظر میباشد که به صورت مستقل قابلیت استقرار را دارد و چنانچه سیستم دچار مشکل شود، منشاء تغییرات کاملا مشخصی میباشد و میتوان سریعتر سیستم را به وضعیت قابل اطمینان بازگرداند. این ویژگی یکی از مهمترین دلایلی میباشد که شرکتهایی مانند Netflix و Amazon به پیاده سازی این معماری روی آوردهاند.
Organizational Alignment
بسیاری از ما مشکلات مربوط به پروژههای بزرگ و تیمهای بزرگ را تجربه کردهایم و این مشکلات زمانیکه اعضای تیم بهصورت متمرکز در کنار هم نباشند، افزایش پیدا میکند. ما میدانیم که اگر یک تیم کوچک، بر روی قطعه کد کوچکتری کار کند، میتواند بسیار موثرتر باشد تا زمانیکه یک تیم بزرگ، درگیر یک کد بزرگ شود.
مایکرو سرویسها این امکان را به ما میدهند تا معماری خود را با ساختار سازمانی خود هم راستا کنیم و به ما کمک میکنند تا با تقسیم ساختار نرم افزار به بخشهای کوچکتر وایجاد تیمهای کوچکتر مختص هر بخش، بازدهی و تاثیر تیمها را در سازمان، افزایش دهیم.
Composability
یکی از ویژگیهای کلیدی که در سیستمهای توزیع شده و سرویس گرا به آن وعده داده میشود، قابلیت استفاده مجدد از functionalityهای سیستم میباشد. مایکرو سرویسها این امکان را برای ما فراهم میکنند تا functionality های سیستم، به روشهای مختلف و با اهداف گوناگونی مورد استفاده قرار گیرند. اینکه استفاده کنندگان نرمافزار ما چگونه از آن استفاده میکنند، برای ما مهم است. در حال حاضر ما باید درباره راههای مختلفی که میتوانند قابلیتهای سیستم را باهم ترکیب کنند تا در برنامههای وب، موبایل و یا ابزارهای پوشیدنی مورد استفاده قرار گیرند، فکر کنیم. در مایکرو سرویس تفکر ما این است که بخشهای مختلف سیستم خود را از هم جدا کنیم و این بخشها توسط استفاده کنندههای بیرونی قابل دسترسی باشند و با تغییر شرایط بتوانیم بخشهای گوناگونی را بسازیم.
Optimizing for Replaceability
اگر شما در یک سازمان متوسط و یا بزرگ، مشغول به کار باشید، ممکن است با یک سیستم بزرگ و قدیمی مواجه شده باشید که در گوشهای از سازمان در حال استفاده میباشد و هیچ کسی رغبت نزدیک شدن به آن و دست بردن در آن را ندارد و اگر کسی از شما بپرسد «چرا نمیتوان آن را تغییر داد؟» خواهید گفت این کار، بسیار پرریسک و پردردسر است.
با استفاده از معماری مایکروسرویس، هزینه این تغییرات به مراتب کمتر و تغییرات با ضریب اطمینان بالاتری انجام میشوند.
سلام من در ویو خودم نمیتونم اطلاعاتم رو تو kendo.grid ببینم و برای من یک لیست استرینگ در ویو نمایش داده میشه و به این شکل در کنترلر و ویو کد نویسی کردم .
و ویو
و یک لیست استرینگ بهم در عمل خروجی میده و از خود قالب kendogrid خبری نیست . من اطلاعات رو به طور json پاس میدم و ajaxi میگیرم.
این سوال رو در چند سایت پرسیدم و به جوابی برایش نرسیدم. و نمیدونم ایراد کدهای نوشته شده ام کجاست!
public class EFController : Controller { // // GET: /EF/ public ActionResult AjaxConnected([DataSourceRequest] DataSourceRequest request ) { using (var dbef=new dbTestEntities()) { IQueryable<Person> persons = dbef.People; DataSourceResult result = persons.ToDataSourceResult(request); return Json(result.Data,JsonRequestBehavior.AllowGet); } } }
@{ ViewBag.Title = "AjaxConnected"; } <h2>AjaxConnected</h2> @(Html.Kendo().Grid<TelerikMvcApp2.Models.Person>( ) .Name("Grid") .DataSource(builder => builder .Ajax() .Read(operationBuilder => operationBuilder.Action("AjaxConnected", "EF")) ) .Columns(factory => { factory.Bound(person => person.personId); factory.Bound(person => person.Name); factory.Bound(person => person.LastName); }) .Pageable() .Sortable())
حالا قبلش همچین خطلایی داشتم که به allowget ایراد میگرفت ولی در کل با JsonRequestBehavior.AllowGet حل شد و حالا فقط یه لسیت بهم خروجی میده! و از ظاهر گرید خبری نیست. و اگر به جای json نوشته بشه view و با ویو return کنم ظاهر kendogrid رو دارم اما خروجی دارای مقداری نیست!
اینم خروجی استرینگ من :(
[{"personId":1,"Name":"Amin","LastName":"Saadati"}, {"personId":2,"Name":"Fariba","LastName":"Ghochani "},{"personId":4,"Name":"Milad","LastName":"Rahman i"},{"personId":5,"Name":"rima","LastName":"rad"}, {"personId":6,"Name":"ali","LastName":"kiva"},{"pe rsonId":7,"Name":"sahel","LastName":"abasi"},{"per sonId":8,"Name":"medi","LastName":"ghaem"},{"perso nId":9,"Name":"mino","LastName":"kafash"},{"person Id":10,"Name":"behzad","LastName":"tizro"},{"perso nId":11,"Name":"toti","LastName":"saadati"},{"pers onId":12,"Name":"parinaz","LastName":"karami"},{"p ersonId":13,"Name":"sadegh","LastName":"hojati"},{ "personId":14,"Name":"milad","LastName":"ebadipor" },{"personId":15,"Name":"farid","LastName":"riazi" },{"personId":16,"Name":"said","LastName":"abdoli" },{"personId":17,"Name":"behzad","LastName":"ariaf ar"},{"personId":18,"Name":"jamshid","LastName":"k otahi"}]
متشکرم
پیشتر مطلبی را در مورد ایجاد Drop Down Listهای به هم پیوسته توسط jQuery Ajax در این سایت مطالعه کرده بودید. شبیه به همان مطلب را اینبار قصد داریم توسط Kendo UI پیاده سازی کنیم.
مدلهای برنامه
در اینجا قصد داریم لیست گروهها را به همراه محصولات مرتبط با آنها، توسط دو drop down list نمایش دهیم:
از ویژگی JsonIgnore جهت عدم درج لیست محصولات، در خروجی JSON نهایی تولیدی گروهها، استفاده شدهاست.
منبع داده JSON سمت سرور
پس از مشخص شدن مدلهای برنامه، اکنون توسط دو اکشن متد، لیست گروهها و همچنین لیست محصولات یک گروه خاص را با فرمت JSON بازگشت میدهیم:
بار اولی که صفحه بارگذاری میشود، توسط یک درخواست Ajax ایی، لیست گروهها دریافت خواهد شد. سپس با انتخاب یک گروه، اکشن متد GetProducts جهت بازگرداندن لیست محصولات آن گروه، فراخوانی میگردد.
در اینجا به عمد از JsonConvert.SerializeObject استفاده شدهاست تا ویژگی JsonIgnore کلاس گروهها، توسط کتابخانهی JSON.NET مورد استفاده قرار گیرد (ASP.NET MVC برخلاف ASP.NET Web API به صورت پیش فرض از JSON.NET استفاده نمیکند).
کدهای سمت کاربر برنامه
کدهای جاوا اسکریپتی Kendo UI را جهت تعریف دو drop down list به هم مرتبط و آبشاری، در ادامه ملاحظه میکنید:
دراپ داون اول، به صورت متداولی تعریف شدهاست. ابتدا فیلدهای Text و Value هر ردیف آن مشخص و سپس منبع داده آن به اکشن متد GetCategories تنظیم گردیدهاست. به این ترتیب با اولین بار مشاهدهی صفحه، این دراپ داون پر خواهد شد.
سپس دراپ دوم که وابستهاست به دراپ داون اول، با این نکات طراحی شدهاست:
الف) خاصیت autoBind آن به false تنظیم شدهاست. به این ترتیب این دراپ داون در اولین بار نمایش صفحه، به سرور جهت دریافت اطلاعات مراجعه نخواهد کرد.
ب) خاصیت cascadeFrom آن به id دراپ داون اول تنظیم شدهاست.
ج) در منبع دادهی آن دو تغییر مهم وجود دارند:
- خاصیت serverFiltering به true تنظیم شدهاست. این مورد سبب خواهد شد تا آیتم گروه انتخاب شده، به سرور ارسال شود.
- خاصیت data نیز تنظیم شدهاست. این مورد پارامتر categoryId اکشن متد GetProducts را تامین میکند و مقدار آن از مقدار انتخاب شدهی دراپ داون اول دریافت میگردد.
اگر برنامه را اجرا کنیم، برای بار اول لیست گروهها دریافت خواهند شد:
سپس با انتخاب یک گروه، لیست محصولات مرتبط با آن در دراپ داون دوم ظاهر میگردند:
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.
مدلهای برنامه
در اینجا قصد داریم لیست گروهها را به همراه محصولات مرتبط با آنها، توسط دو drop down list نمایش دهیم:
public class Category { public int CategoryId { set; get; } public string CategoryName { set; get; } [JsonIgnore] public IList<Product> Products { set; get; } } public class Product { public int ProductId { set; get; } public string ProductName { set; get; } }
منبع داده JSON سمت سرور
پس از مشخص شدن مدلهای برنامه، اکنون توسط دو اکشن متد، لیست گروهها و همچنین لیست محصولات یک گروه خاص را با فرمت JSON بازگشت میدهیم:
using System.Linq; using System.Text; using System.Web.Mvc; using KendoUI12.Models; using Newtonsoft.Json; namespace KendoUI12.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); // shows the page. } [HttpGet] public ActionResult GetCategories() { return new ContentResult { Content = JsonConvert.SerializeObject(CategoriesDataSource.Items), ContentType = "application/json", ContentEncoding = Encoding.UTF8 }; } [HttpGet] public ActionResult GetProducts(int categoryId) { var products = CategoriesDataSource.Items .Where(category => category.CategoryId == categoryId) .SelectMany(category => category.Products) .ToList(); return new ContentResult { Content = JsonConvert.SerializeObject(products), ContentType = "application/json", ContentEncoding = Encoding.UTF8 }; } } }
در اینجا به عمد از JsonConvert.SerializeObject استفاده شدهاست تا ویژگی JsonIgnore کلاس گروهها، توسط کتابخانهی JSON.NET مورد استفاده قرار گیرد (ASP.NET MVC برخلاف ASP.NET Web API به صورت پیش فرض از JSON.NET استفاده نمیکند).
کدهای سمت کاربر برنامه
کدهای جاوا اسکریپتی Kendo UI را جهت تعریف دو drop down list به هم مرتبط و آبشاری، در ادامه ملاحظه میکنید:
<!--نحوهی راست به چپ سازی --> <div class="k-rtl k-header demo-section"> <label for="categories">گروهها: </label><input id="categories" style="width: 270px" /> <label for="products">محصولات: </label><input id="products" disabled="disabled" style="width: 270px" /> </div> @section JavaScript { <script type="text/javascript"> $(function () { $("#categories").kendoDropDownList({ optionLabel: "انتخاب گروه...", dataTextField: "CategoryName", dataValueField: "CategoryId", dataSource: { transport: { read: { url: "@Url.Action("GetCategories", "Home")", dataType: "json", contentType: 'application/json; charset=utf-8', type: 'GET' } } } }); $("#products").kendoDropDownList({ autoBind: false, // won’t try and read from the DataSource when it first loads cascadeFrom: "categories", // the id of the DropDown you want to cascade from optionLabel: "انتخاب محصول...", dataTextField: "ProductName", dataValueField: "ProductId", dataSource: { // When the serverFiltering is disabled, then the combobox will not make any additional requests to the server. serverFiltering: true, // the DataSource will send filter values to the server transport: { read: { url: "@Url.Action("GetProducts", "Home")", dataType: "json", contentType: 'application/json; charset=utf-8', type: 'GET', data: function () { return { categoryId: $("#categories").val() }; } } } } }); }); </script> <style scoped> .demo-section { width: 100%; height: 100px; } </style> }
سپس دراپ دوم که وابستهاست به دراپ داون اول، با این نکات طراحی شدهاست:
الف) خاصیت autoBind آن به false تنظیم شدهاست. به این ترتیب این دراپ داون در اولین بار نمایش صفحه، به سرور جهت دریافت اطلاعات مراجعه نخواهد کرد.
ب) خاصیت cascadeFrom آن به id دراپ داون اول تنظیم شدهاست.
ج) در منبع دادهی آن دو تغییر مهم وجود دارند:
- خاصیت serverFiltering به true تنظیم شدهاست. این مورد سبب خواهد شد تا آیتم گروه انتخاب شده، به سرور ارسال شود.
- خاصیت data نیز تنظیم شدهاست. این مورد پارامتر categoryId اکشن متد GetProducts را تامین میکند و مقدار آن از مقدار انتخاب شدهی دراپ داون اول دریافت میگردد.
اگر برنامه را اجرا کنیم، برای بار اول لیست گروهها دریافت خواهند شد:
سپس با انتخاب یک گروه، لیست محصولات مرتبط با آن در دراپ داون دوم ظاهر میگردند:
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.
مطالب دورهها
حذف یک ردیف از اطلاعات به همراه پویانمایی محو شدن اطلاعات آن توسط jQuery در ASP.NET MVC
فرض کنید تعدادی ردیف در گزارشی نمایش داده شدهاند. قصد داریم برای هر
ردیف یک دکمه حذف را قرار دهیم. این حذف باید Ajax ایی باشد؛ به علاوه در
حین حذف ردیف، پویانمایی محو آن ردیف را نیز سبب شود.
مدل و منبع داده برنامه
در اینجا مدل برنامه که ساختار نمایش یک سری مطلب را تهیه
میکند، ملاحظه میکنید؛ به علاوه یک منبع داده فرضی تشکیل شده در حافظه
جهت سهولت دموی برنامه.
کنترلر برنامه
کنترلر برنامه بسیار ساده بوده و نکته خاصی ندارد. در حین
اولین بار نمایش صفحه، لیست مطالب را به View مرتبط ارسال میکند. همچنین
یک اکشن متد حذف ردیفهای نمایش داده شده را نیز در اینجا تدارک دیدهایم.
این اکشن متد از طریق ارسال اطلاعات به صورت Ajax، شماره مطلب را در اختیار
برنامه قرار میدهد که توسط آن در ادامه برای مثال میتوان این رکورد را
از بانک اطلاعاتی حذف کرد. امضای متد DeleteRow بر اساس پارامترهای ارسالی توسط jQuery Ajax مشخص و تنظیم شدهاند:
View برنامه
کدهای View برنامه را در ادامه ملاحظه میکنید. اطلاعات مطالب
دریافتی به صورت یک جدول در صفحه نمایش داده شدهاند. در هر ردیف توسط یک
span که با css تزئین گردیده است، یک دکمه حذف را تدارک دیدهایم. برای
اینکه در حین کار با jQuery بتوانیم id هر ردیف را بدست بیاوریم، این id را
در قسمتی از id این span اضافه شده قرار دادهایم.
در کدهای اسکریپتی صفحه، ابتدا کلیک بر روی کلیه spanهایی که id آنها با row شروع میشود را مونیتور خواهیم کرد:
سپس هر زمان که بر روی یکی از این spanها کلیک شد، میتوان بر اساس span جاری، id و همچنین tableRow مرتبط را استخراج کرد:
اکنون که به این
اطلاعات دسترسی پیدا کردهایم، تنها کافی است آنها را توسط متد ajax به
کنترلر برنامه برای پردازش نهایی ارسال نمائیم. همچنین در پایان کار
عملیات، توسط متدهای fadeTo و remove ایی که ملاحظه میکنید، سبب حذف
نمایشی یک ردیف به همراه پویانمایی محو آن خواهیم شد.
دریافت کدها و پروژه کامل این قسمت
jQueryMvcSample06.zip
مدل و منبع داده برنامه
namespace jQueryMvcSample06.Models { public class BlogPost { public int Id { set; get; } public string Title { set; get; } public string Body { set; get; } } }
using System.Collections.Generic; using jQueryMvcSample06.Models; namespace jQueryMvcSample06.DataSource { /// <summary> /// منبع داده فرضی جهت سهولت دموی برنامه /// </summary> public static class BlogPostDataSource { private static IList<BlogPost> _cachedItems; static BlogPostDataSource() { _cachedItems = createBlogPostsInMemoryDataSource(); } /// <summary> /// هدف صرفا تهیه یک منبع داده آزمایشی ساده تشکیل شده در حافظه است /// </summary> private static IList<BlogPost> createBlogPostsInMemoryDataSource() { var results = new List<BlogPost>(); for (int i = 1; i < 30; i++) { results.Add(new BlogPost { Id = i, Title = "عنوان " + i, Body = "متن ... متن ... متن " + i}); } return results; } public static IList<BlogPost> LatestBlogPosts { get { return _cachedItems; } } } }
کنترلر برنامه
using System.Web.Mvc; using System.Web.UI; using jQueryMvcSample06.DataSource; using jQueryMvcSample06.Security; namespace jQueryMvcSample06.Controllers { public class HomeController : Controller { [HttpGet] public ActionResult Index() { var postsList = BlogPostDataSource.LatestBlogPosts; return View(postsList); } [AjaxOnly] [HttpPost] [OutputCache(Location = OutputCacheLocation.None, NoStore = true)] public ActionResult DeleteRow(int? postId) { if (postId == null) return Content(null); //todo: delete post from db return Content("ok"); } } }
data: JSON.stringify({ postId: postId }),
View برنامه
@model IEnumerable<jQueryMvcSample06.Models.BlogPost> @{ ViewBag.Title = "Index"; var postUrl = Url.Action(actionName: "DeleteRow", controllerName: "Home"); } <h2> حذف یک ردیف از اطلاعات به همراه پویانمایی محو شدن اطلاعات آن</h2> <table> <tr> <th> عملیات </th> <th> عنوان </th> </tr> @foreach (var item in Model) { <tr> <td> <span id="row-@item.Id">حذف</span> </td> <td> @item.Title </td> </tr> } </table> @section JavaScript { <script type="text/javascript"> $(function () { $('span[id^="row"]').click(function () { var span = $(this); var postId = span.attr('id').replace('row-', ''); var tableRow = span.parent().parent(); $.ajax({ type: "POST", url: '@postUrl', data: JSON.stringify({ postId: postId }), contentType: "application/json; charset=utf-8", dataType: "json", complete: function (xhr, status) { var data = xhr.responseText; if (xhr.status == 403) { window.location = "/login"; } else if (status === 'error' || !data || data == "nok") { alert('خطایی رخ داده است'); } else { $(tableRow).fadeTo(600, 0, function () { $(tableRow).remove(); }); } } }); }); }); </script> }
در کدهای اسکریپتی صفحه، ابتدا کلیک بر روی کلیه spanهایی که id آنها با row شروع میشود را مونیتور خواهیم کرد:
$('span[id^="row"]').click(function () {
var span = $(this); var postId = span.attr('id').replace('row-', ''); var tableRow = span.parent().parent();
دریافت کدها و پروژه کامل این قسمت
jQueryMvcSample06.zip
اشتراکها
کتابخانه Multi-Step-Form-Js
Multi Step Form with jQuery validation Demo
- utilizes jquery validation (with or without jquery unobtrusive validation) to validate the form at each step.
- contains customizable header step classes to distinguish between active, complete, and incomplete steps.
- triggers custom change events with relevant step data for custom processing (e.g. updating progress bars)
npm install multi-step-form-js
باید نوع داده ارسالی رو مشخص کنید، بعنوان مثال:
مطالعه بیشتر
function postProduct() { var product = { Name: "SampleProduct", Category: "TestCategory", Price: 10.99 }; $.ajax({ type: 'POST', data: JSON.stringify(product), url: "/api/products", contentType: "application/json" }).done(function (data) { var message = data.Name + ' $:' + data.Price; alert(message); }); }
مطالعه بیشتر
- یک وظیفه در اینجا همیشه در حال اجرا نیست. فقط زمانیکه به تنظیمات خاصیت Schedule آن برسد، اجرا میشود. تمام وظایف پشت صحنه به همین صورت اجرا و مدیریت میشوند. یک حلقه مخصوص بررسی رسیدن به زمانبندی مدنظر وجود دارد و سپس اجرای آن وظیفهی خاص. نمونهی دیگر آن پروژهی « DNTScheduler.Core » است که معادل NET Core. مطلب «انجام کارهای زمانبندی شده در برنامههای ASP.NET توسط DNT Scheduler» هست.
- برای غیرفعال کردن یک Task در مطلب جاری، باید آنرا از لیست سرویسهای ثبت شدهی سیستم حذف کنید (و یا برای معرفی آن به سیستم باید به سیستم تزریق وابستگیها توسط services.AddHostedService اضافه شود).
public static class ServiceCollectionExtensions { public static IServiceCollection Remove<T>(this IServiceCollection services) { var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(T)); if (serviceDescriptor != null) services.Remove(serviceDescriptor); return services; } }
اشتراکها