DCSIMG
Question from Tapuz .Net forum: Create user friendly and search-engine friendly URLs with ASP.Net - Justin myJustin = new Justin( Expriences.Current );

Question from Tapuz .Net forum: Create user friendly and search-engine friendly URLs with ASP.Net

שאלה:

יש לי אתר ASP.net, שאני מעוניינת להפוך את כתובות ה-URL המגיעות ממנו ל-Search Engine Friendly.

 בכל הדוגמאות שמצאתי שמדברות על הנושא, הדרך הבסיסית היא שימוש בפונקציה RewritePath של המחלקה HttpContext.
הפונקציה אמורה "לזייף" את ה-url address של ה-Request כך שאפילו שכתובת העמוד האמיתית היא
 www.mysite.com/mypage.aspx?category=1&product=2 מה שהמשתמש יראה יהיה www.mysite.com/categoryname/productname.html.

 השתמשתי בפונקציה,  קיבלתי שגיאה ולא ברור לי מדוע זה קורה.

 

תשובה:

HttpContext.RewritePath היא מתודה לא סימפטית שצריך להימנע משימוש ישיר בה. למרות היכולות המאוד מוגבלות שלה לבצע סוג יחסית פרימיטיבי של UrlRewriting עדיף להימנע מעבודה מולה היות והיא לא מציגה פתרון כוללני לבעיות שעלולות להיווצר כתוצאה מהשינוי URL. הרבה מאוד פיצ'רים בדוט נט נשברים כאשר מחבלים ישירות ב-HttpContext. למשל, ידוע ש-Themes ו-Master Pages מתחילים לזרוק שגיאות בעבודה עם RewritePath.

לבעיה של UrlRewriting יש שתי פתרונות נפוצים.

הראשון ביניהם מובנה בתוך ASP.Net 2.0 בצורה של תגית <urlMappings> בקובץ ה-web.config. בתוך התגית הזאת (שיושבת כמובן בתוך <system.web>) ניתן להוסיף מיפוי אחד-לאחד של כתובת ספציפית שהלקוח מבקש ולכתובת ספציפית אחרת. כל זה בלי להוריד את השינוי כתובת ללקוח, אלא לבצע הכל שקוף מהלקוח. שזאת למען האמת המטרה. למשל הדוגמה הזאת תפנה כל בקשה מהכתובת Bevrages\Coke.aspx לכתובת פחות ידידותית-למשתמש שתכיל סימונים של המערכת.

        <urlMappings>
            <add url="~\Bevrages\Coke.aspx" mappedUrl="Product.aspx?cat_id=7&prod_id=5" />
        </urlMappings>

מה הבעיה בפתרון המובנה ב-ASP.Net 2.0? הוא מאפשר הפניה רק בין כתובות ספציפיות ולא ביצוע של כללים. מה זה כלל לדוגמה? "תיקח את התיקייה ותחפש אותה כקטגוריה של מוצר ותיקח את השם קובץ ותחפש אותה כשם של מוצר ותזרוק את זה לדף אחר". כלומר, שיש משתנים כלשהם במחרוזת החיפוש, הפריימוורק כבר לא יודע לתמוך בזה.

אגב, הסיבה למגלבה הזו היא מאוד פשוטה, urlMappings נועד לתמוך בפיצ'ר חדש של ASP.Net 2.0 שנקרא app_offline.html וברגע שנשים קובץ כזה בתיקייה של פרוייקט web כל הבקשות לאפליקציה יפנו לדף HTML הסטטי הזה. וככה נוכל למשל להוריד אתר לתחזוקה.

הפתרון הנפוץ לבעיה הזו הוא שימוש בספריית התוכנה החופשית urlrewriting.net. הספרייה מאפשרת כל חיתוך והתאמה בין מחרוזות שנרצה לעשות והכלה של כללים על כל בקשה שהיא מקבלת. הדבר היפה שהיא אפילו מקבלת כללים ב-Regex. למשל הכלל הבא:

    <urlrewritingnet rewriteOnlyVirtualUrls="true" contextItemsPrefix="QueryString" defaultPage="default.aspx" xmlns="http://www.urlrewriting.net/schemas/config/2006/07">
        <rewrites>
            <add name="UrlTest" virtualUrl="^~/Url/([0-9]*)/([0-9]*).aspx"
                 rewriteUrlParameter="ExcludeFromClientQueryString"
                 destinationUrl="~/UrlRewritingTest.aspx?FirstId=$1&SecondId=$2"
                ignoreCase="true"/>
        </rewrites>
    </urlrewritingnet>

הקוד הנ"ל יפנה כל בקשה לכתובת בסגנון Url/1234/4567.aspx לדף UrlRewritingTest.aspx?FirstId=1234&SecondId=45678. העבודה בכללים ולא במוסכמות סטטיות היא חלק מהכוח המאוד רציני של הספריית תוכנה הזו.

ניתן להוריד את הספריית תוכנה הזו כאן:
UrlRewritingNet.UrlRewrite - Home

אם את רוצה גם להיפתר מסיומת ה-ASPX (או כל סיומת אחרת שהפריימוורק מקבל, למשל ASMX) בכדי ליצור כתובת מאוד ידידותית למשתמש, אני ממליץ בחום שתקראי הודעה ישנה שלי בנושא שיתוף בין ה-IIS ל-ASP.Net.

 

שאלת המשך: האם ניתן להשתמש במסד הנתונים בתהליך? למשל ליצור דף בשם myProductName.aspx ושהוא ימצא את ה-ID של myProductName וישלח ל-Product.aspx?id=1234?

שאלה מצויינת.

הכללים שאפשר לראות באתר של UrlRewriting.Net הם הכללים ברירת מחדל, למשל באמת הכלל של Regex שמבצע כל מיני בדיקות, מקבל כל מיני החלטות ואז מבצע בפועל הפנייה. בתוך הכלל הזה יש לוגיקה.

בצורה דומה את יכולה לכתוב לעצמך בקלות רבה RewriteRule משלך. אותם כללים שדיברנו עליהם שה-Regexp הוא דוגמה של כזה כלל שבה עם UrlRewriting, את יכולה לכתוב אחד כזה משלך. אותו RewriteRule מיישם שתי מתודות לא מעניינות ומתודה אחת מאוד מעניינת - RewriteURL שמקבל את ה-Url לשכתוב. בתוך המתודה הזו תוכלי להשתמש למשל ב-Regex.Match כדי להוציא את שתי המילים הרלוונטיות מתוך ה-QueryString, לגשת איתם למסד נתונים ואז להחזיר את ה-URL המתוקן שאת הלוגיקה שלו כתבת במתודה הזו.

העיקר הוא שאת יכולה ליצור לעצמך מחלקה שבאיזהשהו שלב מקבלת את המושכות לידיים ואת יכולה לבצע את ההחלטות שלך ולהכניס את ההיגיון שלך לתוך מנגנון UrlWriting מתפקד לגמרי.
בשביל זה צריך ליישם את אובייקט ה-RewriteRule ו-UrlRewritingProvider שיחזיר את הכלל. בגדול, המקום היחידי שיש בו מחשבה אמיתי זה ב-RewriteRule.RewriteURL ששם את מחליטה לפי ה-URL הנוכחי לאיזה URL להפנות.

עוד על הנושא (ודוגמה על איך הם יישמו את כלל ה-Regexp) אפשר לקרוא במדריך שנמצא בדף הראשי של האתר (הארבעה עמודים האחרונים ב-PDF אאל"ט).

 

קישור: http://www.tapuz.co.il/tapuzforum/main/Viewmsg.asp?forum=831&msgid=89119502

Published Saturday, November 18, 2006 9:10 PM by Justin-Josef Angel [MVP]

Comments

No Comments