PDA

View Full Version : تعريف نود متغير در Web.SiteMap



Mostafa_Dindar
سه شنبه 17 فروردین 1389, 08:52 صبح
سلام ،

از Web.siteMap و SiteMapPath براي breadcrumb ( ردگيري صفحات سايت ) استفاده كردم ، در Web.siteMap نودها رو به صورت استاتيك تعريف كردم ولي صفحاتي وجود دارند كه بر اساس پارامتر كوئري استرينگ صفحات متفاوتي رو نشون ميدن .

مثلا در عين حال كه نودي براي تعريف صفحه خبرها به صورت زير دارم :
<siteMapNode url="~/NewsList.aspx" title="ليست خبرها" description="">

به صفحه اي مثل :

~/NewsDetails.aspx?NewsId=X
هم نياز دارم .

سوال من اين هست كه چطور ميتونم اين كار رو پياده سازي كنم !؟

مرسي

mehdi.mousavi
سه شنبه 17 فروردین 1389, 09:48 صبح
سلام، از Web.siteMap و SiteMapPath براي breadcrumb ( ردگيري صفحات سايت ) استفاده كردم ، در Web.siteMap نودها رو به صورت استاتيك تعريف كردم ولي صفحاتي وجود دارند كه بر اساس پارامتر كوئري استرينگ صفحات متفاوتي رو نشون ميدن. سوال من اين هست كه چطور ميتونم اين كار رو پياده سازي كنم !؟ مرسي

سلام.
XMLSiteMapProvider بطور پیش فرض از چنین سناریویی پشتیبانی نمیکنه. شما می تونید کلاس جدیدی از XmlSiteMapProvider درایو کنید و اینکارو خودتون انجام بدید. خوشبختانه پیاده سازی چنین Provider ای قبلا در اینجا (http://www.csharper.net/blog/custom_sitemapprovider_incorporates_querystring_re liance.aspx#custom_sitemapprovider_incorporates_qu erystring_reliance.aspx) توضیح داده شده.

موفق باشید.

Mostafa_Dindar
سه شنبه 17 فروردین 1389, 12:28 عصر
ممنون از شما آقاي موسوي ،

راه حل اونجا براي من كمي پيچيده به نظر ميرسيد ، من راه حل اين آدرس (http://stackoverflow.com/questions/291908/using-web-sitemap-with-dynamic-urls-url-routing) رو دنبال كردم از اونجايي كه من تنها از SiteMapPath استفاده ميكنم و استفاده ديگري از Web.SiteMap نميكنم يك DynamicSiteMapPath از SiteMapPath درايو كردم

نكته ابهام براي من اين هست كه چطور از اين DynamicSiteMapPath استفاده كنم ؟

سپاسگزارم

mohsen507
سه شنبه 17 فروردین 1389, 21:49 عصر
دوست عزيز LastPhoeinx

لطفا اگر به نتيجه اي رسيديد ,ميشه تو تاپيك اعلام كنيد راه حلشو

ممنون

mohsen507
چهارشنبه 18 فروردین 1389, 00:11 صبح
سلام.
XMLSiteMapProvider بطور پیش فرض از چنین سناریویی پشتیبانی نمیکنه. شما می تونید کلاس جدیدی از XmlSiteMapProvider درایو کنید و اینکارو خودتون انجام بدید. خوشبختانه پیاده سازی چنین Provider ای قبلا در اینجا (http://www.csharper.net/blog/custom_sitemapprovider_incorporates_querystring_re liance.aspxC#‎‎‎‎‎‎‎‎‎‎ustom_s itemapprovider_incorporates_querystring_reliance.a spx) توضیح داده شده.

موفق باشید.


اين روش استفاده شده,( توي لينك معرفي ) است شايدبدرد كسي بخوره
ولي يه نقصي كه داره اينه اگه بخشهاي مختلف مثلا ورزشي وهنري و.. داشته باشي و همه به details پاس بدهند به درستي كار نمي كند. شايد كار من ايراد داشته است :متفکر:

1:ابتدا توي Web.sitemap اين نودو تعريف مي كنيم



<siteMapNode url="~/details.aspx" title="عنوان صفحه" reliantOn="ID" />



ID نام QueryString است.

2:اين كلاسو به پروژه اضافه كرده



public class SmartSiteMapProvider : XmlSiteMapProvider{ public override void Initialize(string name, NameValueCollection attributes) { base.Initialize(name, attributes); this.SiteMapResolve += new SiteMapResolveEventHandler(SmartSiteMapProvider_Si teMapResolve); } SiteMapNode SmartSiteMapProvider_SiteMapResolve(object sender, SiteMapResolveEventArgs e) { if(SiteMap.CurrentNode == null) return null; SiteMapNode temp; temp = SiteMap.CurrentNode.Clone(true); Uri u = new Uri(e.Context.Request.Url.ToString()); SiteMapNode tempNode = temp; while(tempNode != null) { string qs = GetReliance(tempNode, e.Context); if(qs != null) if(tempNode != null) tempNode.Url += qs; tempNode = tempNode.ParentNode; } return temp; } private string GetReliance(SiteMapNode node, HttpContext context) { //Check to see if the node supports reliance if(node["reliantOn"] == null) return null; NameValueCollection values = new NameValueCollection(); string[] vars = node["reliantOn"].Split(",".ToCharArray()); foreach(string s in vars) { string var = s.Trim(); //Make sure the var exists in the querystring if(context.Request.QueryString[var] == null) continue; values.Add(var, context.Request.QueryString[var]); } if(values.Count == 0) return null; return NameValueCollectionToString(values); } private string NameValueCollectionToString(NameValueCollection col) { string[] parts = new string[col.Count]; string[] keys = col.AllKeys; for(int i = 0; i < keys.Length; i++) parts[i] = keys[i] + "=" + col[keys[i]]; string url = "?" + String.Join("&", parts); return url; }}


3:در وب كانفيگ پروايدر و اضافه كرده



<siteMap defaultProvider="SmartSiteMapProvider" enabled="true">
<providers>
<clear />
<add name="SmartSiteMapProvider" type="SmartSiteMapProvider" siteMapFile="web.sitemap" securityTrimmingEnabled="true" />
</providers>
</siteMap>

Mostafa_Dindar
چهارشنبه 18 فروردین 1389, 00:42 صبح
حالا هر صفحه اي با آدرس details.aspx?ID=x درخواست شود Title نود در سايت مپ نمايش داده ميشود.

سلام ، يا شما منظور من رو صحيح متوجه نشدي يا من منظور شما رو !؟

اگر ميخواستم Title صفحه details.aspx?Id=X رو نشون بدم كه اينقدر خودمو اذيت نميكردم !

كافي بود يك نود تعريف كنم بنام details.aspx و Title اون رو هم مقدار دهي كنم و حالا با هر پارامتري هم كه فراخواني بشه همان Title نمايش داده ميشه .

سايتي كه من دارم روش كار ميكنم به 4 زبان هست و ميخوام با توجه به زبان و پارامتر Query String عنوان خبر يا محصول رو در SiteMapPath قرار بدم .

روشي كه اينجا معرفي شده (http://stackoverflow.com/questions/291908/using-web-sitemap-with-dynamic-urls-url-routing) .رو من كاملا Customize كردم . منتها نميدونم چطور از اون DynamicSiteMapPath استفاده كنم :عصبانی++:

mohsen507
چهارشنبه 18 فروردین 1389, 01:02 صبح
سلام
من منظور شما رو متوجه شدم قصدم از زدن اين پست پاسخ به سوال شما نبود


اين روش استفاده شده,( توي لينك معرفي ) است شايدبدرد كسي بخوره


اين پستي كه زدم مربوط به به لينك معرفي شده در پست #2 بود كه يه مثال ساده است كه ميشه يك كلاس جديد XmlSiteMapProvider ساخت و كاراي زيادي ميشه باهاش كرد
كه به صورت اون چيزي كه خودم (مبتدي) فهميدم و شايد درست باشد با بقيه به اشتراك بذارم

ممنون از توجه تون:چشمک:

iman_ad
چهارشنبه 18 فروردین 1389, 02:20 صبح
می شه کلاسی که نوشتی بزاری

mehdi.mousavi
چهارشنبه 18 فروردین 1389, 10:19 صبح
سلام. روشي كه اينجا (http://www.csharper.net/blog/custom_sitemapprovider_incorporates_querystring_re liance.aspxC#%E2%80%8E%E2%80%8Eustom_sitemapprovid er_incorporates_querystring_reliance.aspx)معرف ي شده .رو من كاملا Customize كردم . منتها نميدونم چطور از اون DynamicSiteMapPath استفاده كنم

سلام.
لینکی که دادید کار نمیکنه. برای استفاده از Custom SiteMapProvider ای که ساخته اید، به بخش Plugging the FileSystemSiteMapProvider Provider Into Your Website از این مقاله (http://www.4guysfromrolla.com/articles/020106-1.aspx) رجوع کنید.

البته اگر منظورتون از "نمیدونم چطور استفاده کنم" رو درست متوجه شده باشم.

موفق باشید.

Mostafa_Dindar
چهارشنبه 18 فروردین 1389, 14:41 عصر
لینکی که دادید کار نمیکنه.
سلام ،

حرفتون درسته آقاي موسوي ، آدرس صحيح اين هست (http://stackoverflow.com/questions/291908/using-web-sitemap-with-dynamic-urls-url-routing) كه در پست 3 نيز اشاره كرده بودم .



برای استفاده از Custom SiteMapProvider ای که ساخته اید، به بخش Plugging the FileSystemSiteMapProvider Provider Into Your Website از این مقاله (http://www.4guysfromrolla.com/articles/020106-1.aspx) رجوع کنید.


فكر ميكنم من نتونستم منظورم رو به شما برسونم ،
لينكي كه شما محبت كرديد و در پست 2 به من معرفي كرديد يك Custom SiteMap Provider معرفي كرده .

ولي در اين آدرس (http://stackoverflow.com/questions/291908/using-web-sitemap-with-dynamic-urls-url-routing)يك نفر يك DynamicSiteMapPath از SiteMapPath درايو كرده و به نظرم ساده و جالب بود .

از اونجايي كه من پروژم MultiLingual هست ، DynamicSiteMap رو به صورت زير پياده سازي كردم :

/// <summary>
/// A DynamicSiteMapPath that inherit siteMapPath and support different QueryString parameter
/// </summary>
public class DynamicSiteMapPath : SiteMapPath
{
protected override void InitializeItem(SiteMapNodeItem item)
{
if (item.ItemType != SiteMapNodeItemType.PathSeparator)
{
string url = item.SiteMapNode.Url;
string param = item.SiteMapNode["param"];
HyperLink link = new HyperLink();
switch (param)
{
case "NewsId":
{
// get parameter value
int newsId = Convert.ToInt32(HttpContext.Current.Request.QueryS tring[param]);

News n = NewsManager.SelectSingleItem(newsId, getLang());
// override node link
link.Text = n.Title;
link.ToolTip = n.Title;
link.NavigateUrl = url + "?" + param + "=" + newsId.ToString();
break;
}
case "ProductId":
{
// get parameter value
int productId = Convert.ToInt32(HttpContext.Current.Request.QueryS tring[param]);

Products p = ProductsManager.SelectSingleItem(productId,getLang ());
// override node link
link.Text = p.Title;
link.ToolTip = p.Title;
link.NavigateUrl = url + "?" + param + "=" + productId.ToString();
break;
}
}
item.Controls.Add(link);
}
else
{
// if current node is a separator, initialize as usual
base.InitializeItem(item);
}
}

private string getLang()
{
string siteLang = "fa";
if (HttpContext.Current.Request.Cookies["siteLang"] != null)
siteLang = HttpContext.Current.Request.Cookies["siteLang"].ToString();
return siteLang;
}
}


و Web.siteMap رو هم به صورت زير دارم :


<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/Default.aspx" title="صفحه اصلي " description="به صفحه اصلي بازگرديد">
<siteMapNode url="~/ProductLists.aspx" title="ليست محصولات" description="به ليست محصولات بازگرديد" >
<siteMapNode url="~/ProductDetails.aspx" title="" description="" param="ProductId"/>
</siteMapNode>
<siteMapNode url="~/NewsList.aspx" title="ليست خبرها" description=" به ليست خبرها برگرديد">
<siteMapNode url="~/NewsDetails.aspx" title="" description="" param="NewsId"/>
</siteMapNode>
<siteMapNode url="~/PhotoGallery.aspx" title="گالري عكسها" description="به گالري عكسها برگرديد" />
<siteMapNode url="~/ContactUs.aspx" title="تماس با ما" description="با ما تماس بگيريد" />
</siteMapNode>
</siteMap>

حالا من موندم كه چطور از كلاسي كه نوشتم استفاده كنم ، چون قبلا تنها كافي بود يك كنترل SiteMapPath رو فرمم بزارم .


----------------------
پانوشت :
علت اينكه كدها رو هم اينجا گذاشتم اينه كه در عين حال كه مشكلم برطرف بشه ، دوستان هم در جريان يادگيري مثل من باشند .

mehdi.mousavi
چهارشنبه 18 فروردین 1389, 15:19 عصر
[quote=Lastphoenix;947112]سلام، فكر ميكنم من نتونستم منظورم رو به شما برسونم ،
لينكي كه شما محبت كرديد و در پست 2 به من معرفي كرديد يك Custom SiteMap Provider معرفي كرده. حالا من موندم كه چطور از كلاسي كه نوشتم استفاده كنم ، چون قبلا تنها كافي بود يك كنترل SiteMapPath رو فرمم بزارم .

اوه. درسته... من فکر کردم هنوز دارید اون ایده رو دنبال می کنید و ... اشتباه از من بود. ببخشید. خوب. در مورد استفاده از این DynamicSiteMapPath، شما چند راه پیش رو دارید.

یکی اینکه یک Place Holder ای داشته باشید و بصورت Dynamic توی Page_Load، یه Instance از کلاس DynamicSiteMapPath رو new کنید و به اون Place Holder اضافه کنید. اینکارو کنید، بطور خودکار متود InitializeItem فراخوانی میشه و مشکل رفع میشه.

روش دیگه، اینه که این کلاس رو کنار بقیه Common Control هایی که در پروژه دارید تعریف کنید، سپس مثل بقیه کنترلها توی پروژه استفاده کنید (من اینو هم آزمایش کردم، درست کار کرد):

<uic:DynamicSiteMapPath ID="whatever" runat="server">
</uic:DynamicSiteMapPath>


که uic در واقع TagPrefix ای هستش که من توی پروژه خودم تعریف کرده ام. این کارو هم کنید، متود InitializeItem کلاس شما فراخوانی میشه و شما به هدفتون می رسید.

روش سوم اینه که کنار پروژه خودتون تعریف کنید و با Register Directive اونو به صفحه معرفی کنید. سپس توی صفحه با TagPrefix ای که توی Register Directive معرفی کرده اید، Element رو بصورت Declarative توی صفحه قرار بدید. (من راستش همیشه از روش دوم استفاده میکنم و خودم این روش رو تست نکردم، اما قاعدتا نباید مشکلی وجود داشته باشه).

موفق باشید.