آموزش (jQuery) جی کوئری 5#
خیلی عالی بود - امیدارم وقت داشته باشی پست آموزشی بیشتری بذاری.
مرسی
راهبری در Silverlight به کمک الگوی MVVM
انتشار VS2010
http://launchoffer.appdev.com/
آموزش MongoDb
in this article, I will show how to take a medium-small demo app written using Visual Studio 2013, ASP.NET 4.5, VC 5, and Entity Framework 6 and turn it into a working ASP.NET 5 app employing Visual Studio 2015, MVC 6 and Entity Framework 7. And the new app will happily run on either the .NET 4.6 CLR or the .NET Core CLR. Let's get started.
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
public class PeopleRepository { private List<Person> _people; public PeopleRepository() { _people = new List<Person> { new Person{ Id=1,Age=28,Name="Uthman"}, new Person{ Id=2,Age=27,Name="Vahid"}, new Person{ Id=3,Age=26,Name="Hadi"}, new Person{ Id=4,Age=25,Name="Saman"}, new Person{ Id=5,Age=20,Name="Sirwan"}, }; } public List<Person> GetAll() { return _people; } }
[Route("api/people")] public class PeopleController : Controller { PeopleRepository _repository; public PeopleController() { _repository = new PeopleRepository(); } [HttpGet("")] public IActionResult Get() { return Ok(_repository.GetAll()); } [HttpGet("{id:int}")] public IActionResult Get(int id) { return Ok(_repository.GetAll().FirstOrDefault(p => p.Id == id)); } [HttpPost] public IActionResult Post([FromBody]Person person) { return Ok(person); } [HttpPut("{id:int}")] public IActionResult Put(int id,[FromBody] Person person) { if (id != person.Id) return BadRequest(); return Ok(person); } [HttpDelete("{id:int}")] public IActionResult Delete(int id) { return Ok(); } [HttpPost("avatar")] public IActionResult Post(IFormFile file) { return Ok(); } }
GET http://localhost:59416/api/people
تا به اینجا توانستیم فقط با نوشتن آدرس API مورد نظر، آن را فراخوانی کنیم.
برای ارسال پارامترهایی در هدر درخواست فقط کافیست دقیقا در خط پایین آدرس، به صورت field-name:field-value، هر پارامتری را که میخواهید، به همراه درخواست ارسال کنید. برای نمونه برای API لیست افراد که در بالا تست کردیم، میتوانیم هدر را به صورت زیر تنظیم نماییم :
GET http://localhost:59416/api/people Content-Type: application/json
اجرای درخواست GET برای دریافت یک شخص خاص
GET http://localhost:59416/api/people/1
خروجی آن به صورت زیر میباشد
درخواست POST برای درج کاربر جدید:
POST http://localhost:59416/api/people content-type: application/json { "id": 10, "name": "ali", "age":37 }
بعد از هدرهای درخواست، یک خط خالی ایجاد کنید و پایینتر از خط خالی، میتوانید مقادیر body درخواست را وارد نمایید.
درخواست PUT برای آپدیت یک شخص :
PUT http://localhost:59416/api/people/3 content-type: application/json { "id": 3, "name": "ali", "age":37 }
درخواست DELETE برای حذف شخص:
DELETE http://localhost:59416/api/people/3 content-type: application/application/json
ارسال توکن اعتبارسنجی :
در صورتی که یک API نیاز به اعتبار سنجی دارد و باید توکن را به همراه درخواستی ارسال نمایید، میتوانید در هدر درخواست، همانند زیر، توکن را ارسال نمایید
GET http://localhost:59416/api/people content-type: application/json Authorization: Bearer token
آپلود فایل:
یکی از API هایی که در مثال ابتدای مقاله داشتیم، مربوط به آپلود فایل آواتار هست که از ورودی، یک IFormFile را به عنوان ورودی دریافت میکند. برای آپلود فایل به کمک افزونه Rest Client میتوانیم به صورت زیر فایل را ارسال نماییم
POST http://localhost:59416/api/people/avatar Content-Type: multipart/form-data; boundary=----MyBoundary ------MyBoundary Content-Disposition: form-data; name="file";filename="Studio" content-type: image/png < C:\Users\rahimi\Downloads\Studio.png ------MyBoundary--
قبل از آدرس فایل، وجود > ضروری میباشد.
فعال سازی دکمه Send Request به ازای هر آدرس:
اگر در یک فایل، چند آدرس را همانند عکس زیر داشته باشید، فقط یک دکمهی Send Request وجود خواهد داشت که کلیک بر روی آن منجر به فراخوانی اولین url میشود.
برای داشتن یک دکمه Send Request به ازای هر API، باید بین هر کدام از API ها، حداقل سه تا # قرار دهید.
### Get All People GET http://localhost:59416/api/people content-type: application/json ### Get Person GET http://localhost:59416/api/people/1 ### Create POST http://localhost:59416/api/people content-type: application/json { "id": 10, "name": "ali", "age":37 } ### Edit person PUT http://localhost:59416/api/people/3 content-type: application/json { "id": 3, "name": "ali", "age":37 } ### Delete person DELETE http://localhost:59416/api/people/3 content-type: application/application/json ### Upload Avatar POST http://localhost:59416/api/people/avatar Content-Type: multipart/form-data; boundary=----MyBoundary ------MyBoundary Content-Disposition: form-data; name="file";filename="Studio" content-type: image/png < C:\Users\rahimi\Downloads\Studio.png ------MyBoundary--
افزونهی Rest Client، فراتر از توضیحات این مقاله میباشد. در صورت علاقه و برای مطالعه بیشتر در مورد آن، میتوانید به لینک صفحه افزونه مراجعه نمایید.
یک TextArea ساده را به صفحه اضافه کرده و این افزونه جیکوئری را بر روی آن اجرا میکنید. به این ترتیب TextArea به صورت خودکار تبدیل به یک ویرایشگر مطلوب خواهد شد. برای مثال:
@Html.TextAreaFor(model => model.ArticleBody, htmlAttributes: new { style = "width:98%; height:500px" }) <script type="text/javascript"> $('#ArticleBody').redactor({ autoformat: false, convertDivs: false }); </script>
یک سری مثال نوشته شده با PHP به همراه این ویرایشگر آنلاین هستند که برای ایده گرفتن بد نیستند (البته به این معنا نیست که این ویرایشگر نیازی به PHP دارد. تنها قسمت سمت سرور مثالهای آن با PHP است). برای مثال اگر در PHP از دستور echo برای ارائه یک نتیجه نهایی به ویرایشگر RedActor استفاده شده، معادل آن در ASP.NET MVC مساوی return Content است.
<script type="text/javascript"> $('#ArticleBody').redactor({ imageUpload: "@Url.Action(result: MVC.RedactorUpload.ImageUpload())", fileUpload: "@Url.Action(result: MVC.RedactorUpload.FileUpload())", linkFileUpload: "@Url.Action(result: MVC.RedactorUpload.FileLinkUpload())" , autoformat: false , convertDivs: false }); </script>
همانطور که ملاحظه میکنید از T4MVC برای مشخص سازی مسیرها استفاده شده. برای مثال MVC.RedactorUpload.ImageUpload به این معنا است که در کنترلری به نام RedactorUpload، اکشن متدی به نام ImageUpload پذیرای ارسال فایل ادیتور خواهد بود و به همین ترتیب در مورد سایر پارامترها.
RedactorUploadController هم ساختار بسیار سادهای دارد. برای مثال هر کدام از متدهای آپلود یاد شده یک چنین امضایی دارند:
[HttpPost] public virtual ActionResult ImageUpload(HttpPostedFileBase file) { }
[AllowUploadSpecialFilesOnly(".jpg,.gif,.png")]
در حالت imageUpload، محتوایی به شکل زیر باید بازگشت داده شود:
return Content("<img src='" + path + "' />");
return Content("<a href=" + path + ">" + someName + "</a>");
return Content(path);
همچنین باید دقت داشت که کار ارسال فایل به سرور توسط خود افزونه RedActor انجام میشود و نیازی به کدنویسی ندارد. فقط باید سمت سرور آنرا به نحوی که عنوان شد مدیریت کنید. ابتدا فایل را در سرور ذخیره کنید. سپس باید یک محتوای رشتهای را به نحو یاد شده، ساخت و توسط return Content بازگشت داد.
پ.ن.
قسمتی از مطالب متن فوق در نگارش جدید این ویرایشگر به نحو زیر تغییر کرده است.
<HintPath>..\..\..\packages\T4MVCExtensions.3.15.0\lib\net40\T4MVCExtensions.dll</HintPath>
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
- قسمت post build event باید به صورت ذیل اصلاح شود:
Copy "$(ProjectDir)$(OutDir)*.*" "$(SolutionDir)RabbalShopCMS.Web\bin\"
- در global.asax.cs پروژهی اصلی باید این موارد را حذف کنید:
ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorViewEngine ());
- افزونهی دارای Area نیازی نیست فایل layout داشته باشد. فقط باید دارای یک ViewStart باشد که به layout پروژهی اصلی اشاره کند. این layout از پروژهی پایه دریافت میشود و نه از افزونه. بنابراین فایل layout افزونه باید حذف شود و اضافی است.
- بعد در حالت solution چند پروژهای اجرای دستور ذیل الزامی است: (خیلی مهم)
PM> update-package
- اگر با درخواست یک آدرس، فایل view پروژهی دیگری بازگشت داده شد، ترتیب اضافه شدن PrecompiledMvcEngine را تغییر دهید. برای مثال در پروژهی پلاگین:
ViewEngines.Engines.Insert(0, engine);
ViewEngines.Engines.Add(engine);
- نصب پایتون 2.5 یا 2.6 یا 2.7 که فعلا در سایت آن، نسخهی 2.7 در دسترس هست. توجه داشته باشید که هنوز برای نسخهی 3 پایتون پشتیبانی صورت نگرفته است.
- آخرین نسخهی sdk را هم میتوانید از این آدرس به صورت zip و یا از این آدرس به صورت tar دانلود کنید و در صورتیکه دوست دارید به سورس آن دسترسی داشته باشید یا اینکه از سورسهای مشارکت شده یا غیر رسمی استفاده کنید، از این صفحه آن را دریافت کنید.
(C:\Users\aym\Downloads\addon-sdk-1.17) C:\Users\aym\Downloads\addon-sdk-1.17\bin>
source bin/activate
bash bin/activate
(addon-sdk)~/mozilla/addon-sdk >
آغاز به کار
mkdir fxaddon cd fxaddon cfx init
* lib directory created * data directory created * test directory created * doc directory created * README.md written * package.json written * test/test-main.js written * lib/main.js written * doc/main.md written Your sample add-on is now ready for testing: try "cfx test" and then "cfx run". Have fun!"
{ "name": "fxaddon", "title": "fxaddon", "id": "jid1-QfyqpNby9lTlcQ", "description": "a basic add-on", "author": "", "license": "MPL 2.0", "version": "0.1" }
{ "name": "dotnettips", "title": ".net Tips Updater", "id": "jid1-QfyqpNby9lTlcQ", "description": "This extension keeps you updated on current activities on dotnettips.info", "author": "yeganehaym@gmail.com", "license": "MPL 2.0", "version": "0.1" }
var button= require('sdk/ui/button/action');
buttons.ActionButton({...});
var tgbutton = require('sdk/ui/button/toggle'); var panels = require("sdk/panel"); var self = require("sdk/self"); var button = tgbutton.ToggleButton({ id: "updaterui", label: ".Net Updater", icon: { "16": "./icon-16.png", "32": "./icon-32.png", "64": "./icon-64.png" }, onChange: handleChange }); var panel = panels.Panel({ contentURL: self.data.url("./popup.html"), onHide: handleHide }); function handleChange(state) { if (state.checked) { panel.show({ position: button }); } } function handleHide() { button.state('window', {checked: false}); }
tgbutton.ToggleButton
require('sdk/ui/button/toggle').ToggleButton
Context Menus
var contextMenu = require("sdk/context-menu"); var home = contextMenu.Item({ label: "صفحه اصلی", data: "https://www.dntips.ir/" }); var postsarchive = contextMenu.Item({ label: "مطالب سایت", data: "https://www.dntips.ir/postsarchive" }); var menuItem = contextMenu.Menu({ label: "Open .Net Tips", context: contextMenu.PageContext(), items: [home, postsarchive], image: self.data.url("icon-16.png"), contentScript: 'self.on("click", function (node, data) {' + ' window.location.href = data;' + '});' });
SelectorContext("img")
SelectorContext("img,a[href]")
var tabs = require("sdk/tabs"); var menuItem = contextMenu.Menu({ label: "Open .Net Tips", context: contextMenu.PageContext(), items: [home, postsarchive], image: self.data.url("icon-16.png"), contentScript: 'self.on("click", function (node, data) {' + ' self.postMessage(data);' + '});', onMessage: function (data) { tabs.open(data); } });
var Url="https://www.dntips.ir/search?term="; var searchMenu = contextMenu.Item({ label: "search for", context: [contextMenu.PredicateContext(checkText),contextMenu.SelectionContext()], image: self.data.url("icon-16.png"), contentScript: 'self.on("click", function () {' + ' var text = window.getSelection().toString();' + ' if (text.length > 20)' + ' text = text.substr(0, 20);' + ' self.postMessage(text);'+ '})', onMessage: function (data) { tabs.open(Url+data); } }); function checkText(data) { if(data.selectionText === null) return false; console.log('selectionText: ' + data.selectionText); //handle showing or hiding of menu items based on the text content. menuItemToggle(data.selectionText); return true; }; function menuItemToggle(text){ var searchText="جست و جو برای "; searchMenu.label=searchText+text; };
در قسمت آینده موارد بیشتری را در مورد افزونه نویسی در فایرفاکس بررسی خواهیم کرد و افزونه را تکمیل خواهیم کرد