مطالب
تولید SiteMap استاندارد و ایجاد یک ActionResult اختصاصی برای Return کردن SiteMap تولید شده
یکی از item‌های مهم در بهینه سازی SEO یک وب‌سایت وجود یک SiteMap استاندارد متشکل از لینک‌های موجود در سایت هست که در وب‌سایت‌های داینامیک معمولا این لینک‌ها بر اساس داده‌های موجود در بانک اطلاعاتی ایجاد میشه. برای مثال مطالب، اخبار و ....
در اینجا بنده قبلا یک کلاس برای تولید SiteMap آماده کردم که در پروژه‌های خودم ازش استفاده میکنم. توسط این کلاس میتونید به صورت داینامیک SiteMap وب‌سایت مبتنی بر ASP.NET MVC خودتون رو ایجاد کنید.

برای آشنایی با ساختار یک SiteMap استاندارد میتونید به لینک رسمی روبرو مراجعه کنید : http://www.sitemaps.org/de/protocol.html 

بنده کلاس‌های زیر رو بر مبنای لینک مذکور در سایت رسمی SiteMaps تولید کردم.  بعد از تولید SiteMap نیاز دارید که اون رو مثلا به عنوان خروجی یک ActionResult بازگردونید. برای این کار هم یک کلاس با نام XmlResult  مشتق شده از ActionResult آماده سازی کردم که کلاس تولید شده SiteMap رو Serialize میکنه و به عنوان نتیجه‌ی یک Action باز می‌گردونه .
using System;
using System.Collections;
using System.Web.Mvc;
using System.Xml.Serialization;

namespace Neoox.Core.SeoTools
{
    [XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
    public class Sitemap
    {
        private ArrayList map;

        public Sitemap()
        {
            map = new ArrayList();
        }

        [XmlElement("url")]
        public Location[] Locations
        {
            get
            {
                Location[] items = new Location[map.Count];
                map.CopyTo(items);
                return items;
            }
            set
            {
                if (value == null)
                    return;
                Location[] items = (Location[])value;
                map.Clear();
                foreach (Location item in items)
                    map.Add(item);
            }
        }

        public int Add(Location item)
        {
            return map.Add(item);
        }
    }

    public class Location
    {
        public enum eChangeFrequency
        {
            always,
            hourly,
            daily,
            weekly,
            monthly,
            yearly,
            never
        }

        [XmlElement("loc")]
        public string Url { get; set; }

        [XmlElement("changefreq")]
        public eChangeFrequency? ChangeFrequency { get; set; }
        public bool ShouldSerializeChangeFrequency() { return ChangeFrequency.HasValue; }

        [XmlElement("lastmod")]
        public DateTime? LastModified { get; set; }
        public bool ShouldSerializeLastModified() { return LastModified.HasValue; }

        [XmlElement("priority")]
        public double? Priority { get; set; }
        public bool ShouldSerializePriority() { return Priority.HasValue; }
    }

    public class XmlResult : ActionResult
    {
        private object objectToSerialize;

        public XmlResult(object objectToSerialize)
        {
            this.objectToSerialize = objectToSerialize;
        }

        public object ObjectToSerialize
        {
            get { return this.objectToSerialize; }
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (this.objectToSerialize != null)
            {
                context.HttpContext.Response.Clear();
                var xs = new System.Xml.Serialization.XmlSerializer(this.objectToSerialize.GetType());
                context.HttpContext.Response.ContentType = "text/xml";
                xs.Serialize(context.HttpContext.Response.Output, this.objectToSerialize);
            }
        }
    }
}
 و اما نحوه استفاده از این کلاس‌ها هم خیلی سادست. به مثال زیر توجه کنید ... فقط این نکته رو در نظر داشته باشید که item هایی که به sitemap اضافه میشه واکشی شده از بانک اطلاعاتی هست، در این مثال چون خواستم ساده توضیح داده بشه نحوه استفاده از این کلاس‌ها، این داده‌ها به صورت static در نظر گرفته شد ولی شما میتونید داده‌ها رو بر اساس ساختار بانک اطلاعاتی خودتون واکشی کرده و به SiteMap اضافه کنید تا یک SiteMap کاملا پویا و Dynamic داشته باشید...
        public ActionResult Sitemap()
        {
            Sitemap sm = new Sitemap();
            sm.Add(new Location()
            {
                Url = string.Format("http://www.TechnoDesign.ir/Articles/{0}/{1}", 1, "SEO-in-ASP.NET-MVC"),
                LastModified = DateTime.UtcNow,
                Priority = 0.5D
            });
            return new XmlResult(sm);
        }
نظرات مطالب
نمایش ساختارهای درختی در Blazor
باسلام
با تشکر از مطلب کاربردی ارسالی، کد مربوطه کاملا درست کار میکند ولی وقتی مقادیر جدول Agent را برای ترسیم درخت وابستگی به این کد Assign میکنم در قسمت ChildrenSelector  فقط یک مرحله از Subgroup  را در درخت نشان میدهد. با در صورتی که برای طراحی Entity جدول Agent از مطالب شما در بخش خودارجاع استفاده نموده ام.

    //َAgent Entity
public class Agent:BaseEntity,ISoftDeleteModel { public int AgentId { get; set; } [MaxLength(300, ErrorMessage = "{0} حداکثر می‌تواند شامل {1} کاراکتر باشد")] public string Title { get; set; } public int Sort { get; set; } public bool IsDisplayed { get; set; } = true; [ForeignKey("Parent")] public int? ParentID { get; set; } public bool IsDeleted { get; set; } [InverseProperty("AgentSend")] public ICollection<LetterAgent> LetterAgentsSend { get; set; } [InverseProperty("AgentReceive")] public ICollection<LetterAgent> LetterAgentsReceive { get; set; } public ICollection<UserAgent> UserAgents { get; set; } public Agent? Parent { get; set; } public ICollection<Agent>? SubGroups { get; set; } }
فلوئنت مربوطه برای خود ارجاع کردن SubGroups در انتیتی Agent
            //SelfReferential
            modelBuilder.Entity<Agent>(entity =>
            {
                entity.HasIndex(e => e.ParentID);

                entity.HasOne(d => d.Parent)
                    .WithMany(p => p.SubGroups)
                    .HasForeignKey(d => d.ParentID);
            });
استفاده از کامپوننت درخت
        <DntTreeView
            TRecord="AgentDTO"
            Items="Comments"
            ChildrenSelector="m => m.SubGroups"
            style="list-style: none;"
            ChildrenHtmlAttributes="ChildrenHtmlAttributes">
            <ItemTemplate Context="record">
                <div class="card mb-1">
                    <div class="card-body">
                        <span>@record.Title</span>
                    </div>
                </div>
            </ItemTemplate>
            <EmptyContentTemplate>
                <div class="alert alert-warning">
                    There is no item to display!
                </div>
            </EmptyContentTemplate>
        </DntTreeView>

با تشکر
مطالب
مخفی کردن کوئری استرینگ‌ها در ASP.NET MVC توسط امکانات Routing
ابتدا مدل و منبع داده نمونه زیر را در نظر بگیرید:
using System.Collections.Generic;

namespace TestRouting.Models
{
    public class Issue
    {
        public int IssueId { set; get; }
        public int ProjectId { set; get; }
        public string Title { set; get; }
        public string Body { set; get; }
    }

    public static class IssuesDataSource
    {
        public static IList<Issue> CreateDataSource()
        {
            var results = new List<Issue>();
            for (int i = 0; i < 100; i++)
            {
                results.Add(new Issue { IssueId = i, ProjectId = i, Body = "Test...", Title = "Title " + i });
            }
            return results;
        }
    }
}
به همراه کنترلر زیر برای نمایش لیست اطلاعات و همچنین نمایش جزئیات یک issue انتخابی:
using System.Linq;
using System.Web.Mvc;
using TestRouting.Models;

namespace TestRouting.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var issuesList = IssuesDataSource.CreateDataSource();
            return View(issuesList); //show the list
        }

        public ActionResult Details(int issueId, int projectId)
        {
            var issue = IssuesDataSource.CreateDataSource()
                                        .Where(x => x.IssueId == issueId && x.ProjectId == projectId)
                                        .FirstOrDefault();
            return View(issue);
        }
    }
}
و View زیر کار نمایش لیست بازخوردهای یک پروژه را انجام می‌دهد:
@model IEnumerable<TestRouting.Models.Issue>
@{
    ViewBag.Title = "Index";
}
<h2>
    Issues</h2>
<ul>
    @foreach (var item in Model)
    {
   
        <li>
            @Html.ActionLink(linkText: item.Title,
                     actionName: "Details",
                     controllerName: "Home",
                     routeValues: new { issueId = item.IssueId, projectId = item.ProjectId },
                     htmlAttributes: null)
        </li>
    }
</ul>
در این حالت اگر پروژه را اجرا کنیم، هر لینک نمایش داده شده، چنین فرمی را خواهد داشت:
 http://localhost:1036/Home/Details?issueId=0&projectId=0
سؤال: آیا می‌شود این لینک‌ها را کمی زیباتر و SEO Friendly‌تر کرد؟
برای مثال آن‌را به نحو زیر نمایش داد:
 http://localhost:1036/Home/Details/0/0
پاسخ: بلی. برای اینکار تنها کافی است از امکانات مسیریابی استفاده کنیم:
using System.Web.Mvc;
using System.Web.Routing;

namespace TestRouting
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "IssueDetails",
                url: "Details/{issueId}/{projectId}", //تطابق با یک چنین مسیرهایی
                defaults: new 
                          { 
                                controller = "Home", //کنترلری که این نوع مسیرها را پردازش خواهد کرد
                                action = "Details", // اکشن متدی که نهایتا پارامترها را دریافت می‌کند
                                issueId = UrlParameter.Optional, //این خواص نیاز است هم نام پارامترهای اکشن متد تعریف شوند
                                projectId = UrlParameter.Optional
                          }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}
در اینجا یک route جدید به نام دلخواه IssueDetails پیش از route پیش فرض، تعریف شده است.
این route جدید با مسیرهایی مطابق پارامتر url آن تطابق خواهد یافت. پس از آن کوئری استرینگ متناظر با issueId را به پارامتر issueId اکشن متدی به نام Details و کنترلر Home ارسال خواهد کرد؛ به همین ترتیب در مورد projectId عمل خواهد شد.
ضمنا در url نهایی نمایش داده شده، دیگر اثری از کوئری استرینگ‌ها نبوده و برای نمونه در این حالت، اولین لینک نمایش داده شده شکل زیر را خواهد داشت:
 http://localhost:1036/Home/Details/0/0
 البته باید دقت داشت، یک چنین اصلاح خودکاری تنها در حالت استفاده از متد Html.ActionLink رخ می‌دهد و اگر Urlها را دستی ایجاد کنید، تغییری را مشاهده نخواهید کرد.
نظرات مطالب
تنظیمات مدت زمان اعتبار کاربران در ASP.NET Identity
«.. اون یکی لاگین میمونه ..»
پس از خروج یکی، لاگین‌های دیگر، با اولین درخواستی که به سرور ارسال می‌کنند، وادار به لاگین مجدد خواهند شد (چون بازه زمانی اعتبارسنجی security stamp موجود در کوکی، با اطلاعات جدید کاربر در سرور، به صفر تنظیم شده‌است). بنابراین این مورد صرفا با به روز رسانی security stamp کاربر در بانک اطلاعاتی عملی می‌شود که باید در حین logoff انجام شود:
await _userManager.UpdateSecurityStampAsync(user.Id);
نظرات مطالب
EF Code First #12
با سلام و تشکر از زحمات استاد نصیری
من چند روز پیش مطلبی رو راجع به ساخت attribute برای compare validation در روش code first عنوان کردم(البته در asp.net web form).که در واقع اصلی‌ترین کاربردش همون کاربرد معروف مقایسه رمز عبور و تکرار رمز عبور هست. یه سری کارایی در این زمینه انجام دادم و خواستم در مورد مشکل مربوطه و در کل ، صحیح یا غلط بودن این روش کمکم کنید.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
    public  class CompareAttribute : ValidationAttribute
    {
        public CompareAttribute(string originalProperty, string confirmProperty)
        {
            OriginalProperty = originalProperty;
            ConfirmProperty = confirmProperty;
        }
        public string ConfirmProperty
        {
            get;
            private set;
        }
        public string OriginalProperty
        {
            get;
            private set;
        }
        public override bool IsValid(object value)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            return String.Equals(((User)value).Password, ((User)value).RepeatPassword);
        }
    }
    
تا اینجا یه کلاس تعریف شده که خیلی خلاصه Validation Attribute رو پیاده سازی کرده.این هم از کلاس User ، فقط در حد تعریف property‌های لازم این مثال
 //[CompareAttribute("Password", "RepeatPassword", ErrorMessage = "Not Compare!")]
    public class User
    {
        public Int64 UserId { get; set; }

 [Required(ErrorMessageResourceName = "Password", ErrorMessageResourceType = typeof(ErrorMessageResource))] public String Password { get; set; }

 [NotMapped] [Required(ErrorMessageResourceName = "RepeatPassword", ErrorMessageResourceType = typeof(ErrorMessageResource))] //[CompareAttribute("Password","RepeatPassword" , ErrorMessage = "Not Compare!")] public String RepeatPassword { get; set; } }
مشکل اصلی استفاده از همین compare attribute  هست که ساخته شده .
وقتی اونو بالای کلاس User میزارم کار میکنه.ولی خب این یه کار خیلی زشتیه! چون به ازای همه property‌ها اجرا میشه.ولی وقتی اونو تو جای اصلیش که همون بالای repeat password هست میزارم کار نمیکنه.
یه جورایی مشکل از اینه که نمیشه انگار مقدار property رو به این سمت پاس داد.ولی در حالتی که بالای کلاس میزارمش چون خود کلاس رو پاس میده ، طبیعتاٌ
اسم property‌ها رو هم پیدا میکنه.
ممنون میشم راهنماییم کنید .


مطالب
SortedSet در دات نت 4

SortedSet قرار گرفته در فضای نام System.Collections.Generic دات نت 4، لیستی از اشیاء به صورت خودکار مرتب شده را ارائه می‌دهد. SortedSet نیز همانند HashSet از اعضای منحصربفردی تشکیل خواهد شد اما اینبار به شکلی مرتب شده. برای پیاده سازی آن از red-black tree data structure استفاده شده است که مهم‌ترین مزیت آن امکان افزودن و یا حذف اشیاء به آن بدون کاهش قابل توجه کارآیی برنامه است.

مثال اول:
using System;
using System.Collections.Generic;

namespace SortedSetTest
{
class Program
{
static void sample1()
{
var setRange = new SortedSet<int> { 2, 5, 6, 2, 1, 4, 8 };

foreach (var i in setRange)
{
Console.WriteLine(i);
}
}

static void Main()
{
sample1();
}
}
}
در این مثال با نحوه‌ی ایجاد این لیست جنریک خود مرتب شونده‌ی تکراری نپذیر (!) آشنا می‌شوید. اگر این مثال را اجرا نمائید، خروجی آن مرتب شده است و همچنین تنها شامل یک عدد 2 است (اعضای تکراری را حذف می‌کند).

مثال دوم:

using System;
using System.Collections.Generic;

namespace SortedSetTest
{
class Program
{
static void sample2()
{
var setRange = new SortedSet<int>();
var random = new Random();

for (int counter = 0; counter < 100; counter++)
{
var rnd = random.Next(-180, 181);
if (!setRange.Add(rnd))
{
Console.WriteLine("Couldn't add {0}", rnd);
}
}

Console.WriteLine("Result set:");
foreach (var item in setRange)
{
Console.WriteLine(item);
}
}

static void Main()
{
sample2();
}
}
}
در این مثال نحوه‌ی افزودن اعضای مختلف به این لیست ویژه، توسط متد Add آن بیان شده است. اگر آیتمی در این لیست موجود باشد، مجددا اضافه نشده و حاصل متد Add آن، False خواهد بود.

مثال سوم:
اگر از سایر انواع سفارشی تعریف شده استفاده نمائید، باید روش مقایسه‌ی آن‌ها را نیز با پیاده سازی اینترفیس استاندارد IComparable ارائه دهید؛ در غیر اینصورت با خطای At least one object must implement IComparable متوقف خواهید شد.

using System;
using System.Collections;
using System.Collections.Generic;

namespace SortedSetTest
{
class FileInfo
{
public string Name { set; get; }
public long Size { set; get; }
}

class FileInfoComparer : IComparer<FileInfo>
{
public int Compare(FileInfo x, FileInfo y)
{
var caseiComp = new CaseInsensitiveComparer();
return caseiComp.Compare(x.Name, y.Name);
}
}


class Program
{

static void sample3()
{
var setRange = new SortedSet<FileInfo>(new FileInfoComparer())
{
new FileInfo
{
Name = "file1.txt",
Size = 100
},
new FileInfo
{
Name = "file2.txt",
Size = 10
},
new FileInfo
{
Name = "file3.txt",
Size = 300
}
};

foreach (var item in setRange)
{
Console.WriteLine(item.Name);
}
}

static void Main()
{
sample3();

Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}

در این مثال اشیایی از نوع کلاس FileInfo به لیست ویژه‌ی ما اضافه شده‌اند. برای اینکه امکان مقایسه‌ی آن‌ها فراهم باشد ، کلاس FileInfoComparer با پیاده سازی اینترفیس IComparer ، روش مقایسه دو شیء از این دست را ارائه می‌دهد.

مطالب
استفاده از Unity در پیاده سازی الگوی Service locator
یکی از راهکارهای پیاده سازی IOC یا همان Inversion Of Control در پروژه‌های MVC استفاده از Unity و معرفی آن به DependencyResolver خود دات نت است.
برای آشنایی با Unity و قابلیت‌های آن میتوانید به اینجا و اینجا سر بزنید.
اما برای استفاده از Unity در پروژه‌های MVC کافی است در Global یا فایل راه انداز (bootstrapper ) تک تک انتزاع‌ها (Interface) را به کلاس‌های مرتبط شان معرفی کنید.
var container = new UnityContainer();  
container.RegisterType<ISomeService, SomeService>(new PerRequestLifetimeManager());
container.RegisterType<ISomeBusiness, SomeBusiness>(new PerRequestLifetimeManager());
container.RegisterType<ISomeController, SomeController>(new PerRequestLifetimeManager());
و بعد از ایجاد container از نوع UnityContainer میتوانیم آنرا به MVC معرفی کنیم:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
تا به اینجا به‌راحتی میتوانید از سرویس‌های معرفی شده در پروژه MVC استفاده کنید.
var someService=(ISomeService)DependencyResolver.Current.GetService(typeof(ISomeService));
var data=someService.GetData();
اما اگر بخواهیم از کلاس‌های معرفی شده در Unity در لایه‌های دیگر (مثلا Business) استفاده کنیم چه باید کرد؟
برای هر این مشکل راهکارهای متفاوتی وجود دارد. من در لایه سرویس از Service locator بهره برده ام. برای آشنایی با این الگو اینجا را بخوانید. اکثر برنامه نویسان الگوهای IOC و Service Locator را با هم اشتباه میگیرند یا آنها را اشتباها بجای هم بکار میبرند.
برای درک تفاوت الگوی IOC و Service locator اینجا را بخوانید.

در لایه سرویس یک کلاس Service Factory داریم که قرار است همه سرویس‌ها، برای برقراری ارتباط با یکدیگر از آن استفاده کنند.این کلاس معمولا در لایه سرویس به اشکال گوناگونی پیاده سازی میشود که کارش وهه سازی از Interface‌های درخواستی است. اما برای یکپارچه کردن آن با Unity من آنرا به شکل زیر پیاده سازی کرده ام

public class ServiceFactory : MarshalByRefObject
    {
        static IUnityContainer uContainer = new UnityContainer();
        public static Type DataContextType { get; set; }

        public static void Initialise(IUnityContainer unityContainer, Type dbContextType)
        {
            uContainer = unityContainer;
            DataContextType = dbContextType;
            uContainer.RegisterType(typeof(BaseDataContext), DataContextType, new HierarchicalLifetimeManager());
        }
        public static T Create<T>()
        {
            return (T)Activator.CreateInstance<T>();
        }
        public static T Create<T>(string fullTypeName)
        {
            return (T)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(fullTypeName);
        }
        public static T Create<T>(Type entityType)
        {
            return (T)Activator.CreateInstance(entityType);
        }
        public static dynamic Create(Type entityType)
        {
            return Activator.CreateInstance(entityType);
        }

        public static T Get<T>()
        {
            return uContainer.Resolve<T>();
        }
        public static object Get(Type type)
        {
            return uContainer.Resolve(type);
        }
    }

در این کلاس ما بجای ایجاد داینامیک آبجکت‌ها، از Unity استفاده کرده‌ایم. در همان ابتدا که برنامه‌ی وب ما برای اولین بار اجرا میشود و بعد از Register کردن کلاس‌ها، می‌توانیم container را به صورت پارامتر سازنده به کلاس Service Factory ارسال کنیم. به این ترتیب برای استفاده از سرویس‌ها در لایه Business از Unity بهره میبریم.

البته استفاده از Unity برای DataContext خیلی منطقی نیست و بهتر است نوع DataContext را در ابتدا بگیریم و هرجا نیاز داشتیم با استفاده از متد Create از آن وهله سازی بکنیم.

نظرات مطالب
ASP.NET MVC #13
public class MyViewModel
{
    [Required]
    public string CategoryId { get; set; }

    public IEnumerable<Category> Categories { get; set; }
}

Controller:

public ActionResult Index()
{
   var model = new MyViewModel
   {
       Categories = GetCategories()
   }
   return View(model);
}

View:

@Html.DropDownListFor(
    x => x.CategoryId, 
    new SelectList(Model.Categories, "ID", "CategoryName"), 
    "-- Please select a category --"
)
@Html.ValidationMessageFor(x => x.CategoryId)
نظرات مطالب
EF Code First #1
سلام
1-می خواستم بدونم برای مثال در کلاس  Blog شما
 public class Blog
    {
        public int Id { set; get; }
        public string Title { set; get; }
        public string AuthorName { set; get; }
        public IList<Post> Posts { set; get; }        
    }
EF دقیقا چه زمانی (و با فراخوانی چه متد هایی) از اکسسور‌های set و چه زمانی از get استفاده می‌کند؟
2- اگر در همین کلاس Blog به هر دلیل نیاز باشد که از اکسسورهای خودکار C# استفاده نکنیم کلاس Blog چگونه خواهد شد؟لطفا این کلاس را بدون اکسسور‌های خودکار باز نویسی کنید
get
{
return ?
}
set 
{
//push calculated private field to db ?
}

نظرات مطالب
Blazor 5x - قسمت دهم - مبانی Blazor - بخش 7 - مسیریابی
تعدادی پرسش و پاسخ تکمیلی مباحث مسیریابی

چگونه می‌توان DateTime را به عنوان پارامتر مسیریابی ارسال کرد؟
Blazor از پارامترهایی از نوع DateTime، در حین مسیریابی پشتیبانی می‌کند؛ با این شرط که قید datetime در حین مسیریابی صریحا ذکر شود:
@page "/route/{parameter:datetime}"
یک مثال: کامپوننت index.razor که سبب هدایت به سمت کامپوننت دیگری به همراه ارسال پارامتری از نوع DateTime می‌شود:
@page "/"
@inject NavigationManager NavManager
<button @onclick="CurrentTime">Current Time</button>
@code {
    public void CurrentTime()
    {
        NavManager.NavigateTo("/time/" + DateTime.Now);
    }
}
و کامپوننت Time.razor که قادر است این DateTime را دریافت کرده و به یک پارامتر، Bind کند:
@page "/time/{param:datetime}"
<h3>Time</h3>
<p>@Param</p>
@code {
    [Parameter]
    public DateTime Param { get; set; }
}


چگونه می‌توان به عنوان صفحه‌ی جاری دسترسی یافت؟
برای اینکار نیاز است از JavaScript interop استفاده کرد. ابتدا برای مثال تابع عمومی getTitle را که بر اساس DOM API مرورگر کار می‌کند، تهیه می‌کنیم:
window.getTitle = () => {
   return document.title;
};
سپس می‌توان از آن در یک کامپوننت Blazor به صورت زیر استفاده کرد:
@page "/"
@inject IJSRuntime jsRuntime
<h2>Page Title: @Title</h2>
<button class="btn btn-primary" @onclick="@GetTitle">Get Title</button>
@code {
public string Title = "";
    
    public async void GetTitle()
    {
            Title = await jsRuntime.InvokeAsync<string>("getTitle");
     }
}

چگونه می‌توان مسیری را از طریق کدهای برنامه در یک برگه‌ی مجزای مرورگر باز کرد؟
در اینجا نیز می‌توان با استفاده از JavaScript interop، متد استاندارد open مرورگر را فراخوانی کرد و پارامتر اول آن‌را به url مدنظر و پارامتر بعدی آن‌را به blank_ تنظیم کرد تا مرورگر آدرس درخواستی را در یک برگه‌ی جدید باز کند:
@inject IJSRuntime jsRuntime

<button @onclick="NavigateToNewTab">New Tab Navigation</button>
@code {
public async Task NavigateToNewTab()
    {
        string url = "/counter";
        await jsRuntime.InvokeAsync<object>("open", url, "_blank");
    }
}