Sync Framework is a comprehensive synchronization platform that enables collaboration and offline access for applications, services, and devices. Sync Framework features technologies and tools that enable roaming, data sharing, and taking data offline. By using Sync Framework, developers can build synchronization ecosystems that integrate any application with data from any store, by using any protocol over any network.
System.Web.dll System.Web.ApplicationServices.dll
C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies\WebMatrix.Data.dll C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies\WebMatrix.WebData.dll
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog=SimpleMembershipProviderDB;Integrated Security=True;" providerName="System.Data.SqlClient"/> </connectionStrings> <system.web> <roleManager enabled="true" defaultProvider="SimpleRoleProvider"> <providers> <clear/> <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/> </providers> </roleManager> <membership defaultProvider="SimpleMembershipProvider"> <providers> <clear/> <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"/> </providers> </membership> </system.web> </configuration>
using System; using System.Security.Principal; using System.Web.Security; using WebMatrix.WebData; namespace MemberShipConsoleApplication { class Program { static void Main(string[] args) { WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); AddUserAndRolSample(); Login(); if (System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated) RunApp(); } static void AddUserAndRolSample() { if (WebSecurity.UserExists("iman")) return; // No implements in SimpleMembershipProvider : // Membership.CreateUser("iman", "123"); WebSecurity.CreateUserAndAccount("iman", "123"); Roles.CreateRole("admin"); Roles.CreateRole("User"); Roles.AddUserToRole("iman", "admin"); } static void Login() { for (int i = 0; i < 3; i++) { Console.Write("UserName: "); var userName = Console.ReadLine(); Console.Write("Password: "); var password = Console.ReadLine(); if (Membership.ValidateUser(userName, password)) { var user = Membership.GetUser(userName); var identity = new GenericIdentity(user.UserName); var principal = new RolePrincipal(identity); System.Threading.Thread.CurrentPrincipal = principal; Console.Clear(); return; } Console.WriteLine("User Name Or Password Not Valid."); } } static void RunApp() { Console.WriteLine("Welcome To MemberShip. User Name: {0}", System.Threading.Thread.CurrentPrincipal.Identity.Name); if (System.Threading.Thread.CurrentPrincipal.IsInRole("admin")) Console.WriteLine("Hello Admin User!"); Console.Read(); } } }
InitializeDatabaseConnection(string connectionStringName, string userTableName, string userIdColumn, string userNameColumn, bool autoCreateTables)
در این بلاگ میتوان:
- یک مطلب جدید را ارسال کرد.
- مطالب قابل ویرایش و یا حذف هستند.
- مطالب بلاگ قسمت ارسال نظرات دارند.
- امکان گزارشگیری از آخرین نظرات ارسالی وجود دارد.
- سایت صفحات درباره و تماس با ما را نیز دارا است.
ساختار پوشههای برنامه
در تصویر ذیل، ساختار پوشههای برنامه بلاگ را ملاحظه میکنید. چون قسمت سمت کلاینت این برنامه کاملا جاوا اسکریپتی است، پوشههای App، Controllers، Libs، Models، Routes و Templates آن در پوشهی Scripts تعریف شدهاند و به این ترتیب میتوان تفکیک بهتری را بین اجزای تشکیل دهندهی یک برنامهی تک صفحهای وب Emeber.js پدید آورد.
فایل CSS بوت استرپ نیز به پوشهی Content اضافه شدهاست.
دریافت پیشنیازهای سمت کاربر برنامه
در ساختار پوشههای فوق، از پوشهی Libs برای قرار دادن کتابخانههای پایه برنامه مانند jQuery و Ember.js استفاده خواهیم کرد. به این ترتیب:
- نیاز به آخرین نگارشهای Ember.js و همچنین افزونهی Ember-Data آن برای کار سادهتر با دادهها و سرور وجود دارد. این فایلها را از آدرس ذیل میتوانید دریافت کنید (نسخههای نیوگت به دلیل قدیمی بودن و به روز نشدن مداوم آنها توصیه نمیشوند):
http://emberjs.com/builds/#/beta
برای حالت آزمایش برنامه، استفاده از فایلهای دیباگ آن توصیه میشوند (فایلهایی با نام اصلی و بدون پسوند prod یا min). زیرا این فایلها خطاها و اطلاعات بسیار مفصلی را از اشکالات رخ داده، در کنسول وب مرورگرها، فایرباگ و یا Developer tools آنها نمایش میدهند. نسخهی min برای حالت ارائهی نهایی برنامه است. نسخهی prod همان نسخهی دیباگ است با حذف اطلاعات دیباگ (نسخهی production فشرده نشده). نسخهی فشرده شدهی prod آن، فایل min نهایی را تشکیل میدهد.
- دریافت جیکوئری
- آخرین نگارش handlebars.js را از سایت رسمی آن دریافت کنید: http://handlebarsjs.com
- Ember Handlebars Loader: https://github.com/michaelrkn/ember-handlebars-loader
- Ember Data Local Storage Adapter: https://github.com/kurko/ember-localstorage-adapter
ترتیب تعریف و قرارگیری این فایلها را پس از دریافت، در فایل index.html قرار گرفته در ریشهی سایت، در کدهای ذیل مشاهده میکنید:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Ember Blog</title> <link href="Content/bootstrap.css" rel="stylesheet" /> <link href="Content/bootstrap-theme.css" rel="stylesheet" /> <link href="Content/styles.css" rel="stylesheet" /> <script src="Scripts/Libs/jquery-2.1.1.min.js" type="text/javascript"></script> <script src="Scripts/Libs/bootstrap.min.js" type="text/javascript"></script> <script src="Scripts/Libs/handlebars-v2.0.0.js" type="text/javascript"></script> <script src="Scripts/Libs/ember.js" type="text/javascript"></script> <script src="Scripts/Libs/ember-handlebars-loader-0.0.1.js" type="text/javascript"></script> <script src="Scripts/Libs/ember-data.js" type="text/javascript"></script> <script src="Scripts/Libs/localstorage_adapter.js" type="text/javascript"></script> </head> <body> </body> </html>
اصلاح فایل ember-handlebars-loader-0.0.1.js
اگر به فایل ember-handlebars-loader-0.0.1.js مراجعه کنید، مسیر فایلهای قالب handlebars قسمتهای مختلف برنامه را از پوشهی templates واقع در ریشهی سایت میخواند. با توجه به تصویر ساختار پوشهی پروژهی جاری، پوشهی template به داخل پوشهی Scripts منتقل شدهاست و نیاز به یک چنین اصلاحی دارد:
url: "Scripts/Templates/" + name + ".hbs",
<system.webServer> <staticContent> <mimeMap fileExtension=".hbs" mimeType="text/x-handlebars-template" /> </staticContent> </system.webServer>
مزیت استفاده از نسخهی دیباگ ember.js در حین توسعهی برنامه
نسخهی دیباگ ember.js علاوه بر به همراه داشتن خطاهای بسیار جامع و توضیح علل مشکلات، مواردی را که در آینده منسوخ خواهند شد نیز توضیح میدهد:
برای مثال در اینجا عنوان شدهاست که دیگر از linkTo استفاده نکنید و آنرا به link-to تغییر دهید.
همچنین اگر از مرورگر کروم استفاده میکنید، افزونهی Ember Inspector را نیز میتوانید نصب کنید تا اطلاعات بیشتری را از جزئیات مسیریابیهای تعریف شده و قالبهای Ember.js بتوان مشاهده کرد. این افزونه به صورت یک برگهی جدید در Developer tools آن ظاهر میشود.
ایجاد شیء Application
همانطور که در قسمتهای پیشین نیز عنوان شد (^ و ^ )، یک برنامهی Ember.js با تعریف وهلهای از شیء Application آن آغاز میشود. برای این منظور به پوشهی App مراجعه کرده و فایل جدید Scripts\App\blogger.js را اضافه کنید؛ با این محتوا:
Blogger = Ember.Application.create();
<script src="Scripts/App/blogger.js" type="text/javascript"></script>
تعاریف مسیریابی و قالبها
اکنون در ادامه قصد داریم لیستی از عناوین مطالب ارسالی را نمایش دهیم. در ابتدا این عناوین را از یک آرایهی ثابت جاوا اسکریپتی دریافت خواهیم کرد و پس از آن از یک Web API کنترلر، جهت دریافت اطلاعات از سرور کمک خواهیم گرفت.
کار router در Ember.js، نگاشت آدرس درخواستی توسط کاربر، به یک route یا مسیریابی تعریف شدهاست. به این ترتیب مدل، کنترلر و قالب آن route به صورت خودکار بارگذاری و پردازش خواهند.
با مراجعه به ریشهی سایت، فایل index.html بارگذاری میشود.
در اینجا تصویری از صفحهی آغازین بلاگ را مشاهده میکنید. در آن صفحهی posts همان ریشهی سایت نیز میباشد. بنابراین نیاز است ابتدا مسیریابی آنرا تعریف کرد. برای این منظور، فایل جدید Scripts\App\router.js را به پوشهی App اضافه کنید؛ با این محتوا:
Blogger.Router.map(function () { this.resource('posts', { path: '/' }); });
همچنین مدخل آنرا نیز در فایل index.html تعریف نمائید:
<script src="Scripts/App/blogger.js" type="text/javascript"></script> <script src="Scripts/App/router.js" type="text/javascript"></script>
افزودن مسیریابی و قالب posts
در ادامه فایل جدید Scripts\Templates\posts.hbs را اضافه کنید. به این ترتیب قالب خالی مطالب به پوشهی templates اضافه میشود. محتوای این فایل را به نحو ذیل تنظیم کنید:
<div class="container"> <h1>Emeber.js blog</h1> <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> </div>
برای بارگذاری این قالب نیاز است آنرا به template loader توضیح داده شده در ابتدای بحث، در فایل index.html اضافه کنیم:
<script> EmberHandlebarsLoader.loadTemplates([ 'posts' ]); </script>
افزودن مسیریابی و قالب about
در ادامه قصد داریم صفحهی about را اضافه کنیم. مجددا با افزودن مسیریابی آن به فایل Scripts\App\router.js شروع میکنیم:
Blogger.Router.map(function () { this.resource('posts', { path: '/' }); this.resource('about'); });
<h1>About Ember Blog</h1> <p>Bla bla bla!</p>
<script> EmberHandlebarsLoader.loadTemplates([ 'posts', 'about' ]); </script>
<script type="text/x-handlebars" data-template-name="about"> </script>
برای آزمایش این مسیر و قالب جدید آن، آدرس http://localhost/#/about را بررسی کنید.
اضافه کردن منوی ثابت بالای سایت
روش اول این است که به ابتدای هر دو قالب about.hbs و posts.hbs، تعاریف منو را اضافه کنیم. مشکل اینکار، تکرار کدها و پایین آمدن قابلیت نگهداری برنامه است. روش بهتر، افزودن کدهای مشترک بین صفحات، در قالب application برنامه است. نمونهی آنرا در مثال قسمت قبل مشاهده کردهاید. در اینجا چون قصد نداریم به صورت دستی قالبها را به صفحه اضافه کنیم و همچنین برای ساده شدن نگهداری برنامه، قالبها را در فایلهای مجزایی قرار دادهایم، تنها کافی است فایل جدید Scripts\Templates\application.hbs را به پوشهی قالبهای برنامه اضافه کنیم؛ با این محتوا:
<div class='container'> <nav class='navbar navbar-default' role='navigation'> <ul class='nav navbar-nav'> <li>{{#link-to 'posts'}}Posts{{/link-to}}</li> <li>{{#link-to 'about'}}About{{/link-to}}</li> </ul> </nav> {{outlet}} </div>
<script> EmberHandlebarsLoader.loadTemplates([ 'posts', 'about', 'application' ]); </script>
افزودن مسیریابی و قالب contact
برای افزودن صفحهی تماس با مای سایت، ابتدا مسیریابی آنرا در فایل Scripts\App\router.js تعریف میکنیم:
Blogger.Router.map(function () { this.resource('posts', { path: '/' }); this.resource('about'); this.resource('contact'); });
<h1>Contact</h1> <ul> <li>Phone: ...</li> <li>Email: ...</li> </ul>
<script> EmberHandlebarsLoader.loadTemplates([ 'posts', 'about', 'application', 'contact' ]); </script>
<div class='container'> <nav class='navbar navbar-default' role='navigation'> <ul class='nav navbar-nav'> <li>{{#link-to 'posts'}}Posts{{/link-to}}</li> <li>{{#link-to 'about'}}About{{/link-to}}</li> <li>{{#link-to 'contact'}}Contact{{/link-to}}</li> </ul> </nav> {{outlet}} </div>
تعریف مسیریابی تو در تو در صفحهی contact
در حال حاضر صفحهی Contact، ایمیل و شماره تماس را در همان بار اول نمایش میدهد. میخواهیم این دو را تبدیل به دو لینک جدید کنیم که با کلیک بر روی هر کدام، محتوای مرتبط، در قسمتی از همان صفحه بارگذاری شده و نمایش داده شود.
برای اینکار نیاز است مسیریابی را تو در تو تعریف کنیم:
Blogger.Router.map(function () { this.resource('posts', { path: '/' }); this.resource('about'); this.resource('contact', function () { this.resource('email'); this.resource('phone'); }); });
پس از آن دو فایل قالب جدید Scripts\Templates\email.hbs را با محتوای:
<h2>Email</h2> <p> <span></span> Email name@site.com. </p>
<h2>Phone</h2> <p> <span></span> Call 12345678. </p>
<script> EmberHandlebarsLoader.loadTemplates([ 'posts', 'about', 'application', 'contact', 'email', 'phone' ]); </script>
<h1>Contact</h1> <div class="row"> <div class="col-md-6"> <p> Want to get in touch? <ul> <li>{{#link-to 'phone'}}Phone{{/link-to}}</li> <li>{{#link-to 'email'}}Email{{/link-to}}</li> </ul> </p> </div> <div class="col-md-6"> {{outlet}} </div> </div>
در اینجا نحوهی پردازش مسیریابی contact را ملاحظه میکنید. ابتدا درخواستی جهت مشاهدهی آدرس http://localhost/#/contact دریافت میشود. سپس router این درخواست را به مسیریابی همنامی منتقل میکند. این مسیریابی ابتدا قالب عمومی application را رندر کرده و سپس قالب اصلی و همنام مسیریابی جاری یا همان contact.hbs را رندر میکند. در این صفحه چون مسیریابی تو در تویی تعریف شدهاست، اگر درخواستی برای مشاهدهی http://localhost/#/contact/phone دریافت شود، محتوای آنرا در {{outlet}} قالب contact.hbs جاری رندر میکند.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید:
EmberJS03_01.zip
Nowadays, I am trying to learn different design patterns in object oriented paradigm that are pretty useful to implement generic solutions for different scenarios. Few weeks ago for a job hunt, I got an assignment to do which was a web application that would interact with database, so I took it up as a challenge and decided to make it loosely coupled using design patterns which were applicable in that scenario.
تازه ها در TypeScript
An unexpected error happened; package X-editable has no version null.
15 درس هنگام مهاجرت به .NET Core
2. Building for deployment
3. NetStandard vs NetCoreApp1.0
4. IIS is dead, well sort of
5. HttpModules and HttpHandlers are replaced by new “middleware”
6. FileStream moved to System.IO.FileSystem ???
7. StreamReader constructor no longer works with a file path
8. Platform specific code… like Microsoft specific RSA
9. Newtonsoft changed to default to camel case on field names 🙁
10. Log4net doesn’t work and neither do countless other dependencies, unless you target .NET 4.5!
11. System.Drawing doesn’t exist
12. DataSet and DataTable doesn’t exist
13. Visual Studio Tooling
14. HttpWebRequest weird changes
15. Creating a Windows Service in .NET Core
Asp.Net Core WebSockets Vs SignalR. Which should you use? (Full Course)
In this video we build 2 separate chat applications, one using Asp.Net Core WebSockets and the other using SignalR, allowing you to compare approaches and decide on which one works best for you. In both cases we build them with C#, .NET Core and JavaScript. You’ll also learn about:
- .NET Core Request Pipeline
- Request Delegates
- Asynchronous Programming in .NET (Async / Await)
- Introduction to Dependency Injection