بناءً على تجربتي الشخصية في استخدام ASP.NET، ومن خلال البحث على الإنترنت. لقد وجدت أن طريقة ResolveUrl الخاصة بالصفحة جلبت لنا بعض المشكلات الخطيرة.
المشكلة الأكثر شيوعًا هي أنه لا يمكن استخدامه خارج نطاق الصفحة أو عنصر التحكم.
جميع المشاكل الأخرى هي الأخطاء. على سبيل المثال، لا يمكنه التعامل بشكل صحيح مع بعض عناوين URL التي تقدمها. على سبيل المثال، حاول Page.ResolveUrl("~/test.aspx?param=http://www.test.com"). والنتيجة هي نفس السلسلة التي أدخلتها، دون أي تغييرات. باستخدام العاكس لعرض كود asp.net، وجدت أن آلية تحويل عناوين URL النسبية إلى عناوين URL المطلقة تبحث أولاً عن "://" في السلسلة، وإذا وجدت، فإنها تُرجعها مباشرة. ولذلك، إذا قمت بتمرير معلمة مع ://، فإن سلسلة الاستعلام تكون على ما يرام. نعلم جميعًا أنه يجب ترميز معلمات سلسلة الاستعلام، ولكن إذا لم يكن الأمر كذلك، فيجب أن تظل مقبولة لعنوان URL. على محمل الجد، تحقق من المتصفح الخاص بك.
عبر الإنترنت، الطريقة الموصى بها هي استخدام VirtualPathUtility.ToAbsolute، وهو أمر لطيف ومريح جدًا إذا كنت تقوم بتمرير عنوان URL كسلسلة استعلام،...وإلا، فسيتم طرح استثناء. إذا كان عنوان URL مطلقًا، فسيطرح استثناءً أيضًا!
لذلك قررت أن أبحث عن حل نهائي.
أولاً، أبحث عن متغير جيد يمنحنا المسار الافتراضي أثناء تشغيل التطبيق، دون استخدام سياق الصفحة.
لقد استخدمت HttpRuntime.AppDomainAppVirtualPath. يمكن استخدامه في أي مكان - حتى في عمليات الاسترجاعات المؤقتة! لا تحتوي على شرطة مائلة زائدة في المسار، وقد قام ASP.NET بإزالة الخطوط المائلة بشكل خاص، ولكن يمكننا إصلاحها :-)
بعد ذلك، أجريت بعض الاختبارات باستخدام كود ResolveUrl الأصلي واكتشفت كيفية استبداله بـ AppVirtualPath:
1. عندما يبدأ عنوان URL بشرطة مائلة (/ أو )، فلن يتغير!
2. عندما يبدأ عنوان URL بـ 〜/، سيتم استبداله بـ AppVirtualPath.
3. عندما يكون عنوان URL عنوان URL مطلقًا، فلن يتم تغييره.
4. في أي حالة أخرى (حتى مع البدء بـ 〜 بدلاً من الشرطة المائلة)، سيتم إلحاق عنوان URL بـ AppVirtualPath.
5. عندما يقوم بتعديل عنوان URL، فإنه يقوم أيضًا بإصلاح الخطوط المائلة. قم بإزالة الشرطة المائلة المزدوجة واستبدل بـ /.
شفرة:
شفرة
سلسلة ثابتة عامة ResolveUrl (سلسلة نسبية Url)
{
if (relativeUrl == null) throw new ArgumentNullException("relativeUrl");
إذا (relativeUrl.Length == 0 || RelativeUrl[0] == '/' ||
نسبيًاUrl[0] == '\') return نسبيUrl;
إنت idxOfScheme =
نسبيًاUrl.IndexOf(@"://"، StringComparison.Ordinal);
إذا (idxOfScheme != -1)
{
int idxOfQM = النسبيUrl.IndexOf('?');
إذا كان (idxOfQM == -1 || idxOfQM > idxOfScheme) يُرجع نسبيUrl؛
}
StringBuilder sbUrl = new StringBuilder();
sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/');
// هل وجدت علامة استفهام بالفعل؟
bool FoundQM = false;
bool FoundSlash; // كان الحرف الأخير عبارة عن شرطة مائلة؟
إذا (relativeUrl.Length> 1
&& نسبياUrl[0] == '~'
&& (relativeUrl[1] == '/' || قريبUrl[1] == '\'))
{
نسبيUrl = نسبيUrl.Substring(2);
FoundSlash = true;
}
else FoundSlash = false;
foreach (حرف ج في نسبيUrl)
{
إذا (! وجدتQM)
{
if (c == '?') FoundQM = true;
آخر
{
إذا (ج == '/' || ج == '\')
{
إذا استمر (foundSlash)؛
آخر
{
sbUrl.Append('/');
FoundSlash = true;
يكمل؛
}
}
وإلا إذا (foundSlash) FoundSlash = false؛
}
}
sbUrl.Append(c);
}
إرجاع sbUrl.ToString();
}
بعد إكمال الكود ومقارنة اختبار ResolveUrl الأصلي مرارًا وتكرارًا، بدأت في اختبار الأداء... في معظم الحالات، تم تنفيذ الكود الخاص بي أسرع 2.7 مرة من ResolveUrl الأصلي! لقد قمت أيضًا باختباره داخل حلقة، حيث قمت بتنفيذ الكود 100000 مرة باستخدام عناوين URL مختلفة.
مرجع النص الأصلي: http://www.codeproject.com/KB/aspnet/resolveurl.aspx
المؤلف: تشو تشيلين المصدر: http://zhuqil.cnblogs.com
حقوق الطبع والنشر لهذه المقالة مملوكة للمؤلف ونرحب بإعادة الطباعة، ومع ذلك، يجب الاحتفاظ بهذا البيان دون موافقة المؤلف، ويجب توفير رابط للنص الأصلي في مكان واضح على صفحة المقالة. الحق في متابعة المسؤولية القانونية محفوظ.