تقوم ASP.NET WebService بإرجاع أحرف هراء عند طرح الاستثناءات

StackOverflow https://stackoverflow.com/questions/62965

سؤال

لدي خدمة ويب (ASMX) وفيها طريقة ويب تقوم ببعض الأعمال وتطرح استثناءً إذا لم يكن الإدخال صالحًا.

[ScriptMethod]
[WebMethod]
public string MyWebMethod(string input)
{
    string l_returnVal;

    if (!ValidInput(input))
    {
        string l_errMsg = System.Web.HttpUtility.HtmlEncode(GetErrorMessage());
        throw new Exception(l_errMsg);
    }

    // some work gets done...

    return System.Web.HttpUtility.HtmlEncode(l_returnVal);
} 

مرة أخرى في JavaScript من جانب العميل على صفحة الويب، في وظيفة رد اتصال الخطأ، أعرض الخطأ الخاص بي:

function GetInputErrorCallback(error)
{
    $get('input_error_msg_div').innerHTML = error.get_message();
}

يعمل هذا بشكل رائع وعندما يعود أسلوب الويب الخاص بي (سلسلة)، فإنه يبدو دائمًا مثاليًا.ومع ذلك، إذا كانت إحدى رسائل الخطأ الخاصة بي من الاستثناء الذي تم طرحه تحتوي على حرف خاص، فسيتم عرضها بشكل غير صحيح في المتصفح.على سبيل المثال، إذا كانت رسالة الخطأ تحتوي على ما يلي:

هذا الإدخال غير صالح! (هذا هو ASCII # 146 هناك)

يعرض هذا:

هذا الإدخال غير صالح!

أو:

هل تحب هوسكر دو؟ (آسكي # 252)

يصبح:

هل تحب Hüsker Dü؟

يأتي محتوى رسائل الخطأ من ملفات XML بتشفير UTF-8:

<?xml version="1.0" encoding="UTF-8"?>
<ErrorMessages>
   <Message id="invalid_input">Your input isn’t valid!</Message>
   .
   .
   .
</ErrorMessages>

وبقدر ما يتعلق الأمر بترميز الصفحة، في Web.config الخاص بي، لدي:

<globalization enableClientBasedCulture="true" fileEncoding="utf-8" />

لدي أيضًا وحدة HTTP لتعيين معلمات L10n:

Thread.CurrentThread.CurrentUICulture = m_selectedCulture;
Encoding l_Enc = Encoding.GetEncoding(m_selectedCulture.TextInfo.ANSICodePage);
HttpContext.Current.Response.ContentEncoding = l_Enc;
HttpContext.Current.Request.ContentEncoding = l_Enc;

لقد حاولت تعطيل وحدة HTTP هذه ولكن النتيجة هي نفسها.

تبدو القيم التي يتم إرجاعها بواسطة خدمة الويب (في المتغير l_errMsg) جيدة في مصحح أخطاء VS.ولكن بمجرد السيطرة على البرنامج النصي للعميل، يتم عرضه بشكل غير صحيح.لقد استخدمت Firebug لإلقاء نظرة على الاستجابة وتشوهت الأحرف الخاصة هناك أيضًا.لذلك أجد أنه من الغريب أن تبدو السلاسل التي يتم إرجاعها بواسطة طريقة الويب الخاصة بي جيدة، حتى لو كانت تحتوي على أحرف خاصة.ومع ذلك، عندما أقوم باستثناء من طريقة الويب، تكون الأحرف الخاصة في رسالتها غير صحيحة.كيف يمكنني اصلاح هذا؟

هل كانت مفيدة؟

المحلول

هل أنت متأكد من أن تعيين "fileEncoding" هو ما تريده، وليس "responseEncoding"؟يحدد إعداد fileEncoding كيفية محاولة خادم الويب قراءة ملفات .asmx/.aspx الفعلية من القرص عندما لا يتمكن من تحديد الترميز تلقائيًا.لذا، فإن ضبط هذا على "utf-8" يعني أنه يجب عليك حفظ جميع ملفات .asmx/.aspx الخاصة بك في utf-8.لا أعتقد أن ذات الصلة بالرغم من ذلك.

يحدث التغيير الذي تراه عندما يتم تحليل النص المشفر كـ utf-8 باستخدام ترميز 8 بت (أي.يتم فك تشفير تدفق بايت utf-8 باستخدام وحدة فك ترميز 8 بت، مثل، في حالتك، iso-8859-1/Windows-1252).لذلك من الممكن أن يكون HtmlEncode() الذي تقوم به قبل رمي() الاستثناء خاطئًا بشأن تشفير الإخراج المقصود.فماذا يحدث إذا لم تظهر لك رسالة الخطأ HtmlEncode()؟

(من الناحية الفنية، "ASCII # 252" ليس صحيحًا تمامًا؛يحتوي ASCII على 128 حرفًا؛الفاصلة العليا التي تستخدمها تأتي من ترميز 8 بت، مثل، في حالتك، iso-8859-1/Windows-1252.)

هل أنت متأكد من أنك قمت بتعطيل وحدة HTTP بشكل صحيح؟يبدو أن هذا السطر قد يكون سبب المشكلة:

HttpContext.Current.Response.ContentEncoding = l_Enc;

...لأنه على الأرجح يقوم بتعيين ترميز الإخراج إلى ترميز 8 بت (ما يعادل صفحة رموز ANSI).

لدعم أكبر عدد ممكن من الثقافات، يجب عليك تعيين ترميز الاستجابة إلى utf-8. هذا هو تنسيق Unicode الأكثر دعمًا في المتصفحات (أعتقد أن جميع المتصفحات الحديثة تدعمه)، وUnicode هو البديل الوحيد للتشفيرات المحلية.ومع ذلك، لا أفهم تمامًا ما هي وحدة HTTP التي تستخدمها ولماذا تحتاج إليها، لذلك قد يكون الموقف أكثر تعقيدًا مما أعتقد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top