- Fixed issue when using HotRestart to deploy iOS application.
- Fixed and issue where Xamarin.iOS fails to build with MessagingRemoteException.
- Fixed an issue which would place constant-initialized static local 'const' variables in 'inline' functions which were previously dynamically-initialized in the read-only data segment. This can cause compatibility issues when linking against OBJs compiled with older toolsets.
- Fixed a build error in Xamarin.Android projects that could be encountered when Android layout files contain certain characters.
- Fixed an issue with .resx localization at runtime for Xamarin.Android applications.
- C++ IntelliSense vcpkgsrv.exe frequently crashes with set_parent_scope_on_push.
- Fixed WMI Provider component installation failure.
- Fixed a crash in some cases when displaying the Quick Info tooltip for C++ code.
- Fixed a crash when closing Visual Studio.
- Adds Xcode 11.5 SDK support
- Removes abstract modifier to BGTask
/** * Template Name: NiceAdmin - v2.1.0 * Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/ * Author: BootstrapMade.com * License: https://bootstrapmade.com/license/ */ (function() { "use strict"; /** * Easy selector helper function */ const select = (el, all = false) => { el = el.trim() if (all) { return [...document.querySelectorAll(el)] } else { return document.querySelector(el) } } /** * Easy event listener function */ const on = (type, el, listener, all = false) => { if (all) { select(el, all).forEach(e => e.addEventListener(type, listener)) } else { select(el, all).addEventListener(type, listener) } } /** * Easy on scroll event listener */ const onscroll = (el, listener) => { el.addEventListener('scroll', listener) } /** * Sidebar toggle */ if (select('.toggle-sidebar-btn')) { on('click', '.toggle-sidebar-btn', function(e) { select('body').classList.toggle('toggle-sidebar') }) } /** * Search bar toggle */ if (select('.search-bar-toggle')) { on('click', '.search-bar-toggle', function(e) { select('.search-bar').classList.toggle('search-bar-show') }) } . . . })();
<!DOCTYPE html> <html dir="rtl"> . . . <body> <div id="app">Loading...</div> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="">Reload</a> <a>🗙</a> </div> <script src="_framework/blazor.webassembly.js"></script> <!-- Vendor JS Files --> <script src="assets/vendor/bootstrap/js/bootstrap.bundle.js"></script> <script src="assets/vendor/php-email-form/validate.js"></script> <script src="assets/vendor/quill/quill.min.js"></script> <script src="assets/vendor/tinymce/tinymce.min.js"></script> <script src="assets/vendor/simple-datatables/simple-datatables.js"></script> <script src="assets/vendor/chart.js/chart.min.js"></script> <script src="assets/vendor/apexcharts/apexcharts.min.js"></script> <script src="assets/vendor/echarts/echarts.min.js"></script> <!-- Template Main JS File --> <script src="assets/js/main.js"></script> </body> </html>
/** * Template Name: NiceAdmin - v2.1.0 * Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/ * Author: BootstrapMade.com * License: https://bootstrapmade.com/license/ */ function initilizeNiceAdminJs() { "use strict"; /** * Easy selector helper function */ const select = (el, all = false) => { el = el.trim() if (all) { return [...document.querySelectorAll(el)] } else { return document.querySelector(el) } } /** * Easy event listener function */ const on = (type, el, listener, all = false) => { if (all) { select(el, all).forEach(e => e.addEventListener(type, listener)) } else { select(el, all).addEventListener(type, listener) } } /** * Easy on scroll event listener */ const onscroll = (el, listener) => { el.addEventListener('scroll', listener) } /** * Sidebar toggle */ if (select('.toggle-sidebar-btn')) { on('click', '.toggle-sidebar-btn', function(e) { select('body').classList.toggle('toggle-sidebar') }) } /** * Search bar toggle */ if (select('.search-bar-toggle')) { on('click', '.search-bar-toggle', function(e) { select('.search-bar').classList.toggle('search-bar-show') }) } . . . }
@page "/" @inject IJSRuntime JSRuntime <div> this is index page </div> @code { protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeVoidAsync("initilizeNiceAdminJs");// Initialize main.js after site completely loaded } } }
افزودن دکمهی ویرایش، به رکوردهای لیست اتاقها و نمایش جزئیات رکورد در حال ویرایش
تا اینجا کامپوننت Pages\HotelRoom\HotelRoomUpsert.razor دارای یک چنین مسیریابی است:
@page "/hotel-room/create"
@page "/hotel-room/create" @page "/hotel-room/edit/{Id:int}"
پس از تعریف مسیریابی دریافت پارامتر Id رکورد در حال ویرایش، نحوهی واکنش نشان دادن به آن در کامپوننت HotelRoomUpsert.razor به صورت زیر است:
@code { // ... [Parameter] public int? Id { get; set; } protected override async Task OnInitializedAsync() { if (Id.HasValue) { // Update Mode Title = "Update"; HotelRoomModel = await HotelRoomService.GetHotelRoomAsync(Id.Value); } else { // Create Mode HotelRoomModel = new HotelRoomDTO(); } } // ... }
- سپس میخواهیم در زمان بارگذاری کامپوننت جاری، اگر مقدار Id، تنظیم شده بود، تمام فیلدهای فرم متصل به شیء HotelRoomModel را به صورت خودکار بر اساس اطلاعات رکورد متناظر با آن در بانک اطلاعاتی، مقدار دهی اولیه کنیم.
<EditForm Model="HotelRoomModel" OnValidSubmit="HandleHotelRoomUpsert">
کار مقدار دهی اولیهی فیلدهای یک کامپوننت نیز باید در روال رویداد گردان OnInitializedAsync انجام شود که نمونهای از آن را در کدهای فوق مشاهده میکنید. در این مثال اگر Id مقدار داشته باشد، مقدار آنرا به متد GetHotelRoomAsync ارسال کرده و سپس شیء DTO دریافتی از آنرا به مدل فرم انتساب میدهیم تا فرم ویرایشی، قابل استفاده شود:
در ادامه برای ساده سازی رسیدن به مسیرهایی مانند hotel-room/edit/1، به کامپوننت Pages\HotelRoom\HotelRoomList.razor مراجعه کرده و در همان ردیفی که اطلاعات رکورد یک اتاق را نمایش میدهیم، لینکی را نیز به صفحهی ویرایش آن، اضافه میکنیم:
<tr> <td>@room.Name</td> <td>@room.Occupancy</td> <td>@room.RegularRate.ToString("c")</td> <td>@room.SqFt</td> <td> <NavLink href="@($"hotel-room/edit/{room.Id}")" class="btn btn-primary">Edit</NavLink> </td> </tr>
مدیریت ثبت اطلاعات ویرایش شدهی یک اتاق، در بانک اطلاعاتی
در حین تکمیل این قسمت میخواهیم پیامهایی مانند موفقیت آمیز بودن عملیات را نیز به کاربر نمایش دهیم. به همین جهت مراحل «Blazor 5x - قسمت یازدهم - مبانی Blazor - بخش 8 - کار با جاوا اسکریپت» را برای افزودن کتابخانهی معروف جاوا اسکریپتی Toastr طی میکنیم که شامل این قسمتها است:
- دریافت و نصب بستههای jquery و toastr
- اصلاح فایل Pages\_Host.cshtml برای افزودن مداخل فایلهای CSS و JS بستههای نصب شده
- تعریف فایل جدید wwwroot\js\common.js برای سادگی کار با توابع جاوا اسکریپتی toastr و افزودن مدخل آن به فایل Pages\_Host.cshtml
- تعریف متدهای الحاقی JSRuntimeExtensions ، جهت کاهش کدهای تکراری فراخوانی متدهای toastr و افزودن فضای نام آن به فایل Imports.razor_
جزئیات این موارد را در قسمت یازدهم این سری میتوانید مطالعه کنید و از تکرار آنها در اینجا صرفنظر میشود. همچنین کدهای تکمیل شدهی این قسمت را از انتهای مطلب جاری نیز میتوانید دریافت کنید.
همچنین پیش از تکمیل ادامهی کدهای ویرایش اطلاعات، نیاز است متد IsRoomUniqueAsync را به صورت زیر اصلاح کنیم:
namespace BlazorServer.Services { public interface IHotelRoomService { Task<bool> IsRoomUniqueAsync(string name, int roomId); // ... } } namespace BlazorServer.Services { public class HotelRoomService : IHotelRoomService { // ... public Task<bool> IsRoomUniqueAsync(string name, int roomId) { if (roomId == 0) { // Create Mode return _dbContext.HotelRooms .ProjectTo<HotelRoomDTO>(_mapperConfiguration) .AnyAsync(x => x.Name != name); } else { // Edit Mode return _dbContext.HotelRooms .ProjectTo<HotelRoomDTO>(_mapperConfiguration) .AnyAsync(x => x.Name != name && x.Id != roomId); } } } }
اکنون متد HandleHotelRoomUpsert کامپوننت Pages\HotelRoom\HotelRoomUpsert.razor جهت مدیریت ثبت و ویرایش اطلاعات به صورت زیر تغییر میکند:
// ... @inject IJSRuntime JsRuntime @code { // ... private async Task HandleHotelRoomUpsert() { var isRoomUnique = await HotelRoomService.IsRoomUniqueAsync(HotelRoomModel.Name, HotelRoomModel.Id); if (!isRoomUnique) { await JsRuntime.ToastrError($"The room name: `{HotelRoomModel.Name}` already exists."); return; } if (HotelRoomModel.Id != 0 && Title == "Update") { // Update Mode var updateResult = await HotelRoomService.UpdateHotelRoomAsync(HotelRoomModel.Id, HotelRoomModel); await JsRuntime.ToastrSuccess($"The `{HotelRoomModel.Name}` updated successfully."); } else { // Create Mode var createResult = await HotelRoomService.CreateHotelRoomAsync(HotelRoomModel); await JsRuntime.ToastrSuccess($"The `{HotelRoomModel.Name}` created successfully."); } NavigationManager.NavigateTo("hotel-room"); } }
- در ابتدا عدم تکراری بودن نام اتاق بررسی میشود:
- در آخر بر اساس Id مدل فرم، حالت ویرایش و یا ثبت اطلاعات را تشخیص میدهیم. البته Id مدل فرم، در حالت ثبت اطلاعات نیز صفر است؛ به علت فراخوانی ()HotelRoomModel = new HotelRoomDTO که سبب مقدار دهی Id آن با عدد پیشفرض صفر میشود. بنابراین صرفا بررسی Id مدل، کافی نیست و برای مثال میتوان عنوان تنظیم شدهی در متد OnInitializedAsync را نیز بررسی کرد.
- پس از تشخیص حالت ویرایش و یا ثبت، یکی از متدهای متناظر HotelRoom Service را مانند UpdateHotelRoomAsync و یا CreateHotelRoomAsync فراخوانی کرده و سپس پیامی را به کاربر نمایش داده و او را به صفحهی نمایش لیست اتاقها، هدایت میکنیم:
کدهای کامل این مطلب را از اینجا میتوانید دریافت کنید: Blazor-5x-Part-15.zip
Visual Studio 2017 15.5.7 منتشر شد
Team Explorer support for TLSv1.2
- We have updated the Git and the Git Credential Manager components that ship in Visual Studio.
- The optional Git for Windows component has also been updated.
- This update allows Git to connect to services that have deprecated support for TLSv1 and TLSv1.1 in favor of TLSv1.2.
Issues Fixed in this Release
These are the customer-reported issues addressed in this release:
- Projects targeting .NET Core 2.1 or newer are not supported by Visual Studio 2017 version 15.5.
- Fixed issue where installation of the SDK for .NET Core 2.1 or newer would cause the option to create ASP.NET Core 2.0 Web applications to disappear.
show how easy it is to add real-time functionality to your web applications using ASP.NET Core SignalR. They discuss topics such as targeting with clients, SignalR transports, and options for running your SignalR application in the cloud.
Now, you can even leverage the Hub protocol spec is the available on GitHub if you're interested in creating your own SignalR client.
Angular 2.0 will be built using the TypeScript language. It will embrace TypeScript's idioms for working with immersive web experiences in larger applications.
You can get those same benefits by working with TypeScript and Angular together. In this session, you'll learn how Angular and TypeScript work together to create single page applications. You'll see how you can leverage the features of ECMAScript 6, and still support today's browsers. You'll see how adopting TypeScript can be as easy as changing the extensions on your .js files. How you use the TypeScript features is completely in your control.
پیاده سازی DbContext مورد نیاز
برای ساخت DbContext میتوان به صورت زیر عمل نمود:
namespace FsWeb.Repositories open System.Data.Entity open FsWeb.Models type FsMvcAppEntities() = inherit DbContext("FsMvcAppExample") do Database.SetInitializer(new CreateDatabaseIfNotExists<FsMvcAppEntities>()) [<DefaultValue()>] val mutable books: IDbSet<Guitar> member x.Books with get() = x.books and set v = x.books <- v
اگر syntax زبان #F برایتان نامفهوم است میتوانید از این دوره کمک بگیرید.
پیاده سازی کلاس BookRepository
ابتدا به کدهای زیر دقت کنید:
namespace FsWeb.Repositories type BooksRepository() = member x.GetAll () = use context = new FsMvcAppEntities() query { for g in context.Books do select g } |> Seq.toList
در بخش بعدی بک کوئری از DbSet مورد نظر گرفته میشود. این روش Query گرفتن در F# 3.0 مطرح شده است. در نتیجه در نسخههای قبلی آن (F# 2.0) اجرای این کوئری باعث خطا میشود. اگر قصد دارید با استفاده از F# 2.0 کوئریهای خود را ایجاد نماید باید به طریق زیر عمل نمایید:
ابتدا از طریق nuget اقدام به نصب package ذیل نمایید:
FSPowerPack.Linq.Community
query <@ seq { for g in context.Books -> g } @> |> Seq.toList
[<HandleError>] type BooksController(repository : BooksRepository) = inherit Controller() new() = new BooksController(BooksRepository()) member this.Index () = repository.GetAll() |> this.View
نکته : تنظیمات مروط به ConnectionString را فراموش نکنید:
<add name="FsMvcAppExample" connectionString="YOUR CONNECTION STRING" providerName="System.Data.SqlClient" />