dotnet new angular
در مورد تنظیمات سمت سرور AngularJS 2.0 در ASP.NET Core 1.0، در قسمت «معرفی بستهی نیوگت Microsoft.AspNetCore.SpaServices» بیشتر بحث شدهاست.
- «قابلیت Attribute Routing در ASP.NET MVC 5»
- «Attribute Routing در ASP.NET MVC 5»
ASP.NET MVC #12
+ مراجعه کنید به مطالب زیر برای توضیحات بیشتر و تکمیلی:
RadioButtonList در ASP.NET MVC
CheckBoxList در ASP.NET MVC
ASP.NET MVC #3
ASP.NET MVC 3 RTM
ASP.NET MVC 3 Tools Update
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddNodeServices(); }
حال میتوانید به وهلهای از اینترفیس INodeServices، از طریق تزریق وابستگیها دسترسی داشته باشید. اینترفیس INodeServices یک Api میباشد و مشخص میکند که کدام قطعه از کد NET. میتواند کد جاوااسکریپتی را که در محیط Node اجرا میشود، فراخوانی کند. همچنین میتوانید از خاصیت FromServices برای دریافت وهلهای از اینترفیس INodeServices در اکشن خود استفاده نمایید.
public async Task<IActionResult> Add([FromServices] INodeServices nodeServices) { var num1 = 10; var num2 = 20; var result = await nodeServices.InvokeAsync<int>("AddModule.js", num1, num2); ViewData["ResultFromNode"] = $"Result of {num1} + {num2} is {result}"; return View(); }
سپس کد جاوااسکریپتی متناظر با تابعی را که توسط متد InvokeAsync فراخوانی میشود، به صورت زیر مینویسیم:
module.exports = function(callback, num1, num2) { var result = num1 + num2; callback(null, result); };
حال بیاییم مثالی دیگر را مرور کنیم. میخواهیم از صفحه وب درخواستی، عکسی را تهیه کنیم. بدین منظور از کتابخانه url-to-image استفاده میکنیم. برای نصب آن دستور npm install --save url-to-image را در خط فرمان تایپ میکنیم.
بعد از اتمام نصب این بسته، متدی را برای دریافت اطلاعات ارسالی این کتابخانه تدارک میبینیم.
[HttpPost] public async Task<IActionResult> GenerateUrlPreview([FromServices] INodeServices nodeServices) { var url = Request.Form["Url"].ToString(); var fileName = System.IO.Path.ChangeExtension(DateTime.UtcNow.Ticks.ToString(), "jpeg"); var file = await nodeServices.InvokeAsync<string>("UrlPreviewModule.js", url, System.IO.Path.Combine("PreviewImages", fileName)); return Content($"/Home/Download?img={fileName}"); } public IActionResult Download() { var image = Request.Query["img"].ToString(); var fileName = System.IO.Path.Combine("PreviewImages", image); var isExists = System.IO.File.Exists(fileName); if (isExists) { Response.Headers.Add($"Content-Disposition", "attachment; filename=\"" + image + "\""); var bytes = System.IO.File.ReadAllBytes(fileName); return File(bytes, "image/jpeg"); } else { return NotFound(); } }
سپس متد UrlPreviewModule.js را به صورت زیر مینویسیم:
var urlToImage = require('url-to-image'); module.exports = function (callback, url, imageName) { urlToImage(url, imageName).then(function () { callback(null, imageName); }).catch(function (err) { callback(err, imageName); }); };
سرویسهای Node به توسعه دهندگان ASP.NET Core امکان استفاده از اکوسیستم NPM را که دارای قابلیتهای فراوانی میباشد، میدهد.
همه ما با DisplayAttribute در DataAnnotaion آشنا هستیم. چیزی شبیه زیر برای یک موجودیت:
public class Student{ [Display(Name="نام خانوادگی")] public string FamilyName { get; set;} }
با استفاده از tag helper ای به نام asp-for میتوان متادیتای Name را به کاربر، در سمت رابط کاربری نشان داد؛ برای مثال:
<label asp-for="FamilyName"></label>
و یا موقع اعتبارسنجی میتوان به جای نشان دادن نام FamilyName از نام مفهومتری مانند نام خانوادگی استفاده نمود.
چه خوب بود اگر میشد علاوه بر نام، توصیفی از فیلد نیز برای آن در این قسمت وجود داشته باشد؛ به عبارت دیگر اگر کد زیر را داشتیم:
[Display( Name = "نام خانوادگی", Description = "بهتر است فقط در اینجا نام خانوادگی شخص وارد شود")] public string FamilyName{ get; set; }
بتوان از tag helper ای مانند زیر استفاده نمود:
<span asp-description-for="FamilyName"></span>
که در نهایت چنین خروجی html ای داشته باشیم:
<span>بهتر است فقط در اینجا نام خانوادگی شخص وارد شود</span>
برای این منظور میتوان از کلاس زیر بهره برد:
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; [HtmlTargetElement("div", Attributes = ForAttributeName)] [HtmlTargetElement("p", Attributes = ForAttributeName)] [HtmlTargetElement("span", Attributes = ForAttributeName)] public sealed class DescriptionForTagHelper : TagHelper { private const string ForAttributeName = "asp-description-for"; [HtmlAttributeName(ForAttributeName)] public ModelExpression For { get; set; } = default!; public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } var description = For.Metadata.Description; if (description != null) { // Do not update the content if another tag helper // targeting this element has already done so. if (!output.IsContentModified) { var childContent = await output.GetChildContentAsync(); if (childContent.IsEmptyOrWhiteSpace) { output.Content.SetHtmlContent(description); } else { output.Content.SetHtmlContent(childContent); } } } } }
کلاس DescriptionForTagHelper از کلاس پایه TagHelper ارث بری نموده است و متد ProcessAsync آن به نحوی که asp-description-for را بپذیرد override شده است.
حوزه اعمال این tag helper به span، p و div محدود شده است؛ اما میتوان با گذاشتن یک ستاره (*) آن را به کل المانهای html اعمال کرد.