RewritePath מתנהג כמו Redirect!

ציפי81

New member
RewritePath מתנהג כמו Redirect!

יש לי אתר ASP.net, שאני מעוניינת להפוך את כתובות ה-URL המגיעות ממנו ל-Search Engine Friendy. בכל הדוגמאות שמצאתי שמדברות על הנושא, הדרך הבסיסית היא שימוש בפונקציה RewritePath של המחלקה HttpContext. הפונקציה אמורה "לזייף" את ה-url address של ה-Request כך שאפילו שכתובת העמוד האמיתית היא www.mysite.com/mypage.aspx?category=1&product=2 מה שהמשתמש יראה יהיה www.mysite.com/categoryname/productname.html. השימוש בפונקציה אמור באופן בסיסי להיות דרך ה-Global.asax בארוע Application_BeginRequest. הכנתי לצורך הניסוי דוגמא פשוטה מאוד, בה עבור כל request שמתקבל יתבצע RewritePath לעמוד ספציפי. קיבלתי שגיאה - אני מצרפת צילום מסך, ולא ברור לי מדוע זה קורה.
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs) ' Fires at the beginning of each request Dim Incoming As HttpContext = HttpContext.Current Dim strCurrentPath As String Dim strCustomPath As String strCurrentPath = Incoming.Request.Path strCurrentPath = strCurrentPath.ToLower() strCustomPath = "yyy.aspx" 'rewrite the URL Incoming.RewritePath(strCustomPath) End Sub​
אולי כדאי להעיר שבMSDN כתוב לגבי הפונקציה RewritePath: RewritePath is used in cookieless session state. האם זו הבעיה שלי?
 

ציפי81

New member
גם בדוגמא הזו קיבלתי שגיאה דומה

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

ציפי81

New member
סליחה, טעות

כאן השגיאה היא מסוג שונה. זה היה במקום אחר שקיבלתי את אותה שגיאה. האם מישהו מכיר את הנושא ותוכל לענות יותר באריכות?
 

yonigold

New member
תשובתי

למה את חושבת שהוא מתנהג כמו REDIRECT? את הרי פונה לדף TTT ורוצה שהוא בעצם יטען את YYY. אילו היה כאן REDIRECT אזי הכתובת שהיתה מופיעה לך בדפדפן היתה YYY (כי הוא היה אומר לדפדפן "לך לשם ידידי"). הכתובת נשארה אותו כתובת משמע לא היתה כאן בקשה להפניה. משום מה הוא לא מצליח לטעון את YYY - האם קיים אצלך דף כזה באותה ספריה?
 

Justin Angel

New member
קה פרובלמה מואי צ'יקיטה?

HttpContext.RewritePath היא מתודה לא סימפטית שצריך להימנע משימוש ישיר בה. למרות היכולות המאוד מוגבלות שלה לבצע סוג יחסית פרימיטיבי של UrlRewriting עדיף להימנע מעבודה מולה היות והיא לא מציגה פתרון כוללני לבעיות שעלולות להיווצר כתוצאה מהשינוי URL. הרבה מאוד פיצ'רים בדוט נט נשברים כאשר מחבלים ישירות ב-HttpContext. לפתרון של 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.
 

ציפי81

New member
תודה על כל ההסברים, ושאלה:

הנושא של כללים אכן חשוב לי מאוד. אבל... הסיבה שרציתי להשתמש ישירות באותה מתודה היא העובדה שביקשתי לשלוף נתונים מה=DB ב-BeginRequest, ולתת שם של עמוד לא כמספר - שזה מה שמתקבל ב-querystring אלא כשם - לדוגמא, לא מספר יצרן אלא שם היצרן. לפי דבריך אני יכולה להסיק שהמקסימום שאני יכולה לעשות הוא להשתמש בפרמטרים כדי לקבל צורה יותר מאורגנת שלהם, אולם אין לי אפשרות להשתמש בשליפות. אני צודקת? (במקרה הגרוע אחשוב על שליחת השם כפרמטר)
 

Justin Angel

New member
קה פרובלמה מואי צ'יקיטה?

שאלה מצויינת. החוקים שאפשר לראות באתר המוצר הם החוקים ברירת המחדל, למשל באמת הכלל של Regex שמבצע כל מיני בדיקות, מקבל כל מיני החלטות ואז מבצע בפועל הפנייה. בתוך הכלל הזה יש לוגיקה. בצורה דומה את יכולה לכתוב לעצמך בקלות רבה RewriteRule משלך. אותו RewriteRule מיישם שתי מתודות לא מעניינות ומתודה אחת מאוד מעניינת - RewriteURL שמקבל את ה-Url לשכתוב. בתוך המתודה הזו תוכלי להשתמש למשל ב-Regex.Match כדי להוציא את שתי המילים הרלוונטיות מתוך ה-QueryString, לגשת איתם למסד נתונים ואז להחזיר את ה-URL המתוקן שאת הלוגיקה שלו כתבת במתודה הזו. העיקר הוא שאת יכולה ליצור לעצמך מחלקה שבאיזהשהו שלב מקבלת את המושכות לידיים ואת יכולה לבצע את ההחלטות שלך ולהכניס את ההיגיון שלך לתוך מנגנון UrlWriting מתפקד לגמרי. בשביל זה צריך ליישם את אובייקט ה-RewriteRule ו-UrlRewritingProvider שיחזיר את הכלל. בגדול, המקום היחידי שיש בו מחשבה אמיתי זה ב-RewriteRule.RewriteURL ששם את מחליטה לפי ה-URL הנוכחי לאיזה URL להפנות. עוד על הנושא (ודוגמה על איך הם יישמו כלל) אפשר לקרוא במדריך שנמצא בדף הראשי של האתר (הארבעה עמודים האחרונים ב-PDF אאל"ט).
 

pintyo

New member
עוד פתרון אפשרי: isapi_rewrite

זהו כלי שדורש התקנה על השרת, חינמי עבור אתר אחד על ה IIS, כך שלא מתאים לכולם. בעייה אחת בעבודה בדוט-נט - תצטרכי לשנות את ה action של הדפים שלך, דבר שמחייב התערבות ברנדור של הדפים, לאחר שעשית זאת, יטויים רגולריים את יכולה לשנות את הכתובות שלך לכל כתובת אפשרית, לא צורך בסיומת כלשהי.
 
למעלה