หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
Microsoft Dataverse รองรับหลายภาษา หากคุณต้องการให้โซลูชันของคุณติดตั้งสำหรับองค์กรที่มีภาษาพื้นฐานที่แตกต่างกันหรือมีการจัดเตรียมหลายภาษา ให้คำนึงถึงสิ่งนี้เมื่อวางแผนโซลูชันของคุณ ตารางต่อไปนี้แสดงกลยุทธ์ที่จะใช้พร้อมกับส่วนประกอบโซลูชันเพื่อรวมไว้ในโซลูชันที่รองรับหลายภาษา
กลวิธี | ชนิดส่วนประกอบของโซลูชัน |
---|---|
ทรัพยากรเว็บสตริง (RESX) | ทรัพยากรบนเว็บ |
ฉลากฝังตัว | การนำทางของแอปพลิเคชัน (แผนผังไซต์) Ribbon |
การส่งออกและนำเข้าการแปล | แอตทริบิวต์ แผนภูมิ แดชบอร์ด เอนทิตี้ ความสัมพันธ์ของเอนทิตี ฟอร์ม ข้อความ ชุดตัวเลือก มุมมอง |
การแปลภาษาในสตริงภาษาฐาน | แม่แบบสัญญา บทบาทการเชื่อมต่อ กระบวนการ (เวิร์กโฟลว์) Security role โปรไฟล์ความปลอดภัยของฟิลด์ |
ไม่จำเป็นต้องแปลเป็นภาษาท้องถิ่น | ขั้นตอนการประมวลผลข้อความ SDK ปลายทางการบริการ |
แยกส่วนประกอบของแต่ละภาษา | แม่แบบของบทความ แม่แบบอีเมล แม่แบบจดหมายเวียน รายงาน กล่องโต้ตอบ |
ใช้ทรัพยากรเว็บ XML เป็นทรัพยากรด้านภาษา | ปลั๊กอินแอสเซมบลี |
ส่วนต่อไปนี้ให้รายละเอียดเพิ่มเติมสำหรับแต่ละกลยุทธ์
ทรัพยากรบนเว็บของสตริง (RESX)
ด้วยทรัพยากรบนเว็บสตริง (RESX) ที่เพิ่มด้วย Dataverse นักพัฒนามีตัวเลือกที่มีประสิทธิภาพมากขึ้นในการสร้างทรัพยากรบนเว็บที่รองรับหลายภาษา ข้อมูลเพิ่มเติม ทรัพยากรบนเว็บสตริง (RESX)
ป้ายกำกับแบบฝัง
ส่วนประกอบของโซลูชันแต่ละรายการที่ใช้กลยุทธ์นี้ต้องการให้รวมข้อความที่แปลเป็นภาษาท้องถิ่นไว้ในส่วนประกอบโซลูชัน
Ribbon
เมื่อมีการติดตั้งชุดภาษา Ribbon ของแอปพลิเคชันจะแสดงข้อความที่แปลเป็นภาษาท้องถิ่นโดยอัตโนมัติสำหรับข้อความเริ่มต้นทั้งหมดใน Ribbon ป้ายกำกับระบบกำหนดไว้ในค่าแอตทริบิวต์ ResourceId
ที่มีไว้สำหรับใช้ภายในเท่านั้น
เมื่อคุณเพิ่มข้อความของคุณเอง คุณควรใช้องค์ประกอบ <LocLabels>
เพื่อให้ข้อความที่แปลเป็นภาษาท้องถิ่นสำหรับภาษาที่คุณรองรับ ข้อมูลเพิ่มเติม: ใช้ฉลากที่แปลเป็นภาษาท้องถิ่นด้วย RIbbon
SiteMap
เมื่อมีการติดตั้งชุดภาษา ข้อความเริ่มต้นในแถบนำทางแอปพลิเคชันจะแสดงข้อความที่แปลเป็นภาษาท้องถิ่นโดยอัตโนมัติ
หากต้องการแทนที่ข้อความเริ่มต้นหรือเพื่อให้ข้อความของคุณเอง ให้ใช้องค์ประกอบ <Titles>
องค์ประกอบ Titles
ควรมีองค์ประกอบ <Title>
ที่มีข้อความที่แปลเป็นภาษาใดๆ ที่โซลูชันของคุณรองรับ
ถ้าองค์ประกอบ Title
ไม่พร้อมใช้งานสำหรับภาษาที่ผู้ใช้ต้องการ ชื่อเรื่องที่สอดคล้องกับภาษาพื้นฐานขององค์กรจะปรากฏขึ้น
องค์ประกอบ <SubArea>
ช่วยให้ผ่านการตั้งค่าภาษาของผู้ใช้โดยใช้พารามิเตอร์ userlcid
เพื่อให้เนื้อหาที่เป็นเป้าหมายของแอตทริบิวต์ SubArea.Url
สามารถทราบถึงการตั้งค่าภาษาของผู้ใช้และปรับเปลี่ยนตามนั้น
ข้อมูลเพิ่มเติม: การส่งผ่านพารามิเตอร์ไปยัง URL โดยใช้แผนผังเว็บไซต์
การส่งออกและนำเข้าการแปล
ป้ายกำกับที่ปรับให้เข้าได้สำหรับส่วนประกอบโซลูชันในตารางต่อไปนี้สามารถส่งออกสำหรับการแปลเป็นภาษาท้องถิ่น
เอนทิตี | แอตทริบิวต์ | ความสัมพันธ์ |
ชุดตัวเลือกส่วนกลาง | ข้อความเอนทิตี | ฟอร์มเอนทิตี |
มุมมองเอนทิตี (SavedQuery) | แผนภูมิ | แดชบอร์ด |
ป้ายกำกับการแปลและสตริงที่แสดง
คุณสามารถกระทำการกำหนดเองในแอปพลิเคชันโดยใช้ภาษาพื้นฐานเท่านั้น ดังนั้นเมื่อคุณต้องการจัดเตรียมป้ายกำกับที่แปลเป็นภาษาท้องถิ่นและแสดงสตริงสำหรับการปรับแต่งเหล่านี้ คุณต้องส่งออกข้อความของป้ายกำกับเพื่อให้สามารถแปลเป็นภาษาอื่น ๆ ที่เปิดใช้งานสำหรับองค์กรได้ ใช้ขั้นตอนต่อไปนี้:
ตรวจสอบให้แน่ใจว่าองค์กรที่คุณทำงานอยู่มีการติดตั้งชุด MUI ทั้งหมดและภาษาที่จัดเตรียมไว้สำหรับภาษาที่คุณต้องการให้คำแปล
สร้างโซลูชันของคุณและแก้ไขส่วนประกอบ
หลังจากที่คุณพัฒนาโซลูชันของคุณเสร็จแล้ว ให้ใช้ฟังก์ชัน "ส่งออกการแปล" สิ่งนี้จะสร้างกระดาษคำนวณ Office Excel (CrmTranslations.xml) ที่มีป้ายกำกับทั้งหมดที่ต้องการการแปล
ในกระดาษคำนวณ ระบุคำแปลที่เกี่ยวข้อง
นำเข้าการแปลกลับมาเป็นองค์กร Dataverse แบบเดิมโดยใช้ฟังก์ชัน "นำเข้าการแปล" และเผยแพร่การเปลี่ยนแปลงของคุณ
ในครั้งต่อไปที่มีการส่งออกโซลูชัน จะมีการแปลทั้งหมดที่คุณให้ไว้
เมื่อนำเข้าโซลูชัน จะมีการยกเลิกป้ายกำกับภาษาที่ไม่มีในระบบเป้าหมายและคำเตือนจะถูกบันทึก
หากไม่มีการระบุป้ายกำกับสำหรับภาษาพื้นฐานของระบบเป้าหมายในแพ็คเกจโซลูชัน จะมีการใช้ป้ายกำกับของภาษาพื้นฐานของแหล่งที่มาแทน ตัวอย่างเช่น หากคุณนำเข้าโซลูชันที่มีป้ายกำกับสำหรับภาษาอังกฤษและภาษาฝรั่งเศสที่มีภาษาอังกฤษเป็นภาษาพื้นฐาน แต่ระบบเป้าหมายมีภาษาญี่ปุ่นและภาษาฝรั่งเศสที่มีภาษาญี่ปุ่นเป็นภาษาพื้นฐาน ระบบจะใช้ป้ายกำกับภาษาอังกฤษแทนป้ายกำกับภาษาญี่ปุ่น ป้ายกำกับภาษาพื้นฐานไม่สามารถเป็น null หรือว่างเปล่าได้
การส่งออกการแปล
ก่อนที่คุณจะส่งออกการแปล คุณต้องติดตั้งชุดภาษาก่อนและจัดเตรียมภาษาทั้งหมดที่คุณต้องการให้แปลเป็นภาษาท้องถิ่น คุณสามารถส่งออกคำแปลในเว็บแอปพลิเคชันหรือโดยใช้ข้อความ ExportTranslationRequest สำหรับข้อมูลเพิ่มเติม ดูที่ ส่งออกเอนทิตีที่กำหนดเองและฟิลด์ข้อความสำหรับการแปล
ข้อความการแปล
เมื่อคุณเปิดไฟล์ CrmTranslations.xml ใน Office Excel คุณจะเห็นเวิร์กชีตสามรายการในตารางต่อไปนี้
แผ่นงาน | รายละเอียด |
---|---|
ข้อมูล | แสดงข้อมูลเกี่ยวกับองค์กรและโซลูชันที่มีการส่งออกป้ายกำกับและสตริง |
สตริงที่แสดง | แสดงสตริงที่แสดงถึงข้อความของข้อความใดๆ ที่เกี่ยวข้องกับส่วนประกอบข้อมูลเมตา ตารางนี้ประกอบด้วยข้อความแสดงข้อผิดพลาดและสตริงที่ใช้สำหรับองค์ประกอบ Ribbon ของระบบ |
ป้ายชื่อในภาษาท้องถิ่น | แสดงข้อความทั้งหมดสำหรับป้ายกำกับส่วนประกอบข้อมูลเมตาใดๆ |
คุณสามารถส่งแฟ้มนี้ไปยังผู้เชี่ยวชาญทางภาษา หน่วยงานแปล หรือบริษัทแปล พวกเขาจะต้องจัดให้มีสตริงการแปลสำหรับเซลล์ว่างใดๆ
หมายเหตุ
สำหรับเอนทิตีแบบกำหนดเองจะมีป้ายกำกับทั่วไปที่แชร์กับเอนทิตีระบบ เช่น สร้างบน หรือ สร้างโดย เนื่องจากคุณได้ติดตั้งและจัดเตรียมภาษาไว้แล้ว หากคุณส่งออกภาษาสำหรับโซลูชันเริ่มต้น คุณอาจจับคู่ป้ายกำกับบางรายการในเอนทิตีที่กำหนดเองของคุณด้วยข้อความที่แปลเป็นภาษาท้องถิ่นสำหรับป้ายกำกับที่เหมือนกันที่ใช้โดยเอนทิตีอื่น ซึ่งสามารถลดต้นทุนการแปลและปรับปรุงความสอดคล้อง
หลังจากข้อความในแผ่นงานได้รับการแปลแล้ว ให้เพิ่มทั้ง CrmTranslations.xml และ [Content_Types].xml เป็นไฟล์. zip ไฟล์เดียวที่บีบอัด ตอนนี้คุณสามารถนำเข้าไฟล์นี้ได้
หากคุณต้องการทำงานกับไฟล์ที่ส่งออกในเชิงภาษาโปรแกรมเป็นเอกสาร XML โปรดดูที่ การรองรับมาตรฐานของ Word, Excel และ PowerPoint สำหรับข้อมูลเกี่ยวกับ schema ที่ไฟล์เหล่านี้ใช้
การนำเข้าข้อความที่แปลแล้ว
สำคัญ
คุณสามารถนำเข้าข้อความที่แปลแล้วกลับไปยังองค์กรเดียวกับที่ส่งออกได้เท่านั้น
หลังจากที่คุณได้ส่งออกและแปลเอนทิตีที่กำหนดเองหรือข้อความแอตทริบิวต์แล้ว คุณจะสามารถนำเข้าสตริงข้อความที่แปลแล้วในแอปพลิเคชันเว็บได้โดยใช้ข้อความ ImportTranslationRequest แฟ้มที่คุณนำเข้าจะเป็นแฟ้มบีบอัดที่มีแฟ้ม CrmTranslations.xml และแฟ้ม [Content_Types].xml เป็นฐาน สำหรับข้อมูลเพิ่มเติม ดูที่ นำเข้าเอนทิตีและฟิลด์ข้อความที่แปล
หลังจากที่คุณได้นำเข้าการแปลที่สมบูรณ์แล้ว ข้อความที่กำหนดเองจะปรากฏให้กับผู้ใช้ที่ทำงานในภาษาที่คุณได้แปลข้อความแล้ว
หมายเหตุ
Dataverse ไม่สามารถนำเข้าข้อความแปลที่มีความยาวเกินกว่า 500 อักขระ ถ้ารายการในไฟล์การแปลของคุณยาวกว่า 500 อักขระ กระบวนการนำเข้าจะล้มเหลว ถ้ากระบวนการนำเข้าล้มเหลว ให้ตรวจทานบรรทัดในแฟ้มที่เป็นสาเหตุให้เกิดความล้มเหลว ลดจำนวนตัวอักษร และลองนำเข้าใหม่อีกครั้ง
เนื่องจากการกำหนดเองสนับสนุนเฉพาะในภาษาพื้นฐานเท่านั้น คุณอาจจะทำงานใน Dataverse รด้วยภาษาพื้นฐานที่ตั้งค่าเป็นการกำหนดลักษณะของภาษาของคุณ เมื่อต้องการตรวจสอบว่าข้อความที่แปลปรากฏ คุณจะต้องเปลี่ยนแปลงการกำหนดลักษณะภาษาของคุณสำหรับส่วนติดต่อผู้ใช้ของ Dataverse เมื่อต้องการดำเนินการงานการกำหนดเองเพิ่มเติม คุณจะต้องเปลี่ยนกลับไปเป็นภาษาพื้นฐาน
การแปลเป็นภาษาท้องถิ่นในสตริงภาษาพื้นฐาน
ส่วนประกอบโซลูชันบางอย่างไม่รองรับหลายภาษา ส่วนประกอบเหล่านี้รวมถึงชื่อหรือข้อความที่มีความหมายในภาษาเฉพาะเท่านั้น หากคุณสร้างโซลูชันสำหรับภาษาใดภาษาหนึ่ง ให้กำหนดส่วนประกอบโซลูชันเหล่านี้สำหรับภาษาพื้นฐานขององค์กรที่ต้องการ
หากคุณต้องการรองรับหลายภาษา กลยุทธ์อย่างหนึ่งคือรวมการแปลเป็นภาษาท้องถิ่นภายในสตริงภาษาพื้นฐาน ตัวอย่างเช่น หากคุณมีบทบาทการเชื่อมต่อที่ชื่อ "เพื่อน" และคุณต้องสนับสนุนภาษาอังกฤษ สเปน และเยอรมัน คุณอาจใช้ข้อความ "เพื่อน (Amigo / Freund)" เป็นชื่อของบทบาทการเชื่อมต่อ เนื่องจากปัญหาเรื่องความยาวของข้อความจึงมีข้อจำกัดเกี่ยวกับจำนวนภาษาที่สามารถใช้กลยุทธ์นี้ได้
ส่วนประกอบโซลูชันบางอย่างในกลุ่มนี้จะปรากฏแก่ผู้ดูแลระบบเท่านั้น เนื่องจากการปรับแต่งระบบสามารถทำได้ในภาษาพื้นฐานขององค์กรเท่านั้นจึงไม่จำเป็นต้องมีหลายภาษา บทบาทด้านความปลอดภัย และ โปรไฟล์ความปลอดภัยภาคสนาม ส่วนประกอบเป็นของกลุ่มนี้
แบบฟอร์มสัญญา ให้คำอธิบายประเภทสัญญาการบริการ สิ่งเหล่านี้ต้องการข้อความสำหรับฟิลด์ ชื่อ และ ตัวย่อ คุณควรพิจารณาใช้ชื่อและตัวย่อที่ไม่ซ้ำกันและเหมาะสมสำหรับผู้ใช้ทุกคนในองค์กร
บทบาทการเชื่อมต่อ อาศัยให้บุคคลเลือกหมวดหมู่และชื่อบทบาทการเชื่อมต่อที่อธิบายได้ เนื่องจากสิ่งเหล่านี้อาจค่อนข้างสั้น ขอแนะนำให้คุณรวมการแปลเป็นภาษาท้องถิ่นในสตริงภาษาพื้นฐาน
กระบวนการ (เวิร์กโฟลว์) ที่เริ่มต้นสำหรับเหตุการณ์ต่างๆ จะสามารถทำงานได้อย่างดีตราบเท่าที่ไม่จำเป็นต้องอัปเดตบันทึกด้วยข้อความที่ต้องการแปล เป็นไปได้ที่จะใช้แอสเซมบลีเวิร์กโฟลว์เพื่อให้ตรรกะที่อาจใช้กับข้อความที่แปลเป็นภาษาท้องถิ่นสามารถใช้กลยุทธ์เดียวกันกับแอสเซมบลีปลั๊กอิน (ใช้ทรัพยากรเว็บ XML เป็นทรัพยากรภาษา)
เวิร์กโฟลว์ตามความต้องการ จำเป็นต้องมีชื่อเพื่อให้ผู้คนสามารถเลือกได้ นอกเหนือจากการรวมการแปลเป็นภาษาท้องถิ่นภายในชื่อของเวิร์กโฟลว์ตามความต้องการแล้ว อีกวิธีหนึ่งคือการสร้างเวิร์กโฟลว์หลายรายการที่มีชื่อที่แปลเป็นภาษาท้องถิ่นซึ่งแต่ละรายการเรียกว่ากระบวนการรองเดียวกัน อย่างไรก็ตาม ผู้ใช้ทั้งหมดจะเห็นรายการเวิร์กโฟลว์ตามความต้องการทั้งหมด ไม่ใช่เฉพาะในภาษาอินเทอร์เฟซผู้ใช้ที่ต้องการ
การแปลเป็นภาษาท้องถิ่นไม่จำเป็น
การประมวลผลข้อความ SDK ขั้นตอน and Service ตำแหน่งข้อมูล ส่วนประกอบของโซลูชันไม่เปิดเผยข้อความที่แปลเป็นภาษาท้องถิ่นให้ผู้ใช้ทราบ หากส่วนประกอบเหล่านี้มีชื่อและคำอธิบายที่สอดคล้องกับภาษาพื้นฐานขององค์กรเป็นสิ่งสำคัญ คุณสามารถสร้างและส่งออกโซลูชันที่มีการจัดการ ด้วยชื่อและคำอธิบายในภาษานั้นได้
แยกส่วนประกอบสำหรับแต่ละภาษา
ส่วนประกอบของโซลูชันต่อไปนี้อาจมีข้อความจำนวนมากที่ต้องแปล:
แม่แบบของบทความ
แม่แบบอีเมล
แม่แบบจดหมายเวียน
รายงาน
กล่องโต้ตอบ
สำหรับองค์ประกอบโซลูชันประเภทเหล่านี้ กลยุทธ์ที่แนะนำคือการสร้างส่วนประกอบแยกต่างหากสำหรับแต่ละภาษา ซึ่งหมายความว่าคุณมักจะสร้างโซลูชันที่มีการจัดการฐานที่มีส่วนประกอบโซลูชันหลักของคุณ แล้วแยกโซลูชันที่มีการจัดการ ต่างหากที่ประกอบด้วยองค์ประกอบโซลูชันเหล่านี้สำหรับแต่ละภาษา หลังจากลูกค้าติดตั้งโซลูชันพื้นฐานแล้ว พวกเขาสามารถติดตั้งโซลูชันที่มีการจัดการสำหรับภาษาที่พวกเขาได้เตรียมไว้สำหรับองค์กร
แตกต่างจาก กระบวนการ (เวิร์กโฟลว์) คุณสามารถสร้าง กล่องโต้ตอบ ที่จะแสดงถึงการตั้งค่าภาษาปัจจุบันของผู้ใช้และแสดงกล่องโต้ตอบเฉพาะกับผู้ใช้ภาษานั้น
สร้างกล่องโต้ตอบที่เป็นภาษาท้องถิ่น
ติดตั้งชุดภาษาที่เหมาะสมและจัดเตรียมภาษา
สำหรับข้อมูลเพิ่มเติม โปรดดู คำแนะนำในการติดตั้งชุดภาษา
เปลี่ยนตัวเลือกส่วนบุคคลของคุณเพื่อระบุ ภาษาส่วนติดต่อผู้ใช้ สำหรับภาษาที่คุณต้องการสำหรับการโต้ตอบ
นำทางไปยัง การตั้งค่า และในกลุ่ม ศูนย์ประมวลผล เลือก กระบวนการ
คลิก ใหม่ และสร้างกล่องโต้ตอบในภาษาที่คุณระบุ
หลังจากที่คุณสร้างกล่องโต้ตอบแล้ว ให้เปลี่ยนตัวเลือกส่วนบุคคลของคุณเพื่อระบุภาษาพื้นฐานขององค์กร
ในขณะที่ใช้ภาษาพื้นฐานขององค์กร คุณสามารถไปที่พื้นที่ โซลูชั่น ใน การตั้งค่า และเพิ่มกล่องโต้ตอบที่ถูกแปลเป็นภาษาท้องถิ่นเป็นส่วนหนึ่งของโซลูชัน
กล่องโต้ตอบที่สร้างขึ้นในภาษาอื่นจะปรากฏต่อผู้ใช้ที่ดู Dataverse โดยใช้ภาษานั้น
ใช้ทรัพยากรบนเว็บ XML เป็นทรัพยากรภาษา
ส่วนประกอบโซลูชันแอสเซมบลีปลั๊กอินสามารถส่งข้อความไปยังผู้ใช้ปลายทางได้โดยการส่ง InvalidPluginExecutionException เช่นเดียวกับการสร้างและอัปเดตเรกคอร์ด ปลั๊กอินไม่สามารถใช้ไฟล์ทรัพยากรได้ ต่างจากเว็บทรัพยากร Silverlight
เมื่อปลั๊กอินต้องการข้อความที่แปลเป็นภาษาท้องถิ่น คุณสามารถใช้ทรัพยากรบนเว็บ XML เพื่อจัดเก็บสตริงที่แปลเป็นภาษาท้องถิ่นเพื่อให้ปลั๊กอินสามารถเข้าถึงได้เมื่อจำเป็น โครงสร้างของ XML เป็นตัวเลือกของคุณ แต่คุณอาจต้องการทำตามโครงสร้างที่ใช้ไฟล์ทรัพยากร ASP.NET (.resx) เพื่อสร้างทรัพยากรเว็บ XML แยกกันสำหรับแต่ละภาษา ตัวอย่างเช่น ต่อไปนี้เป็นทรัพยากรบนเว็บ XML ที่มีชื่อว่า localizedString.en_US ที่เป็นไปตามรูปแบบที่ใช้ ไฟล์ Resx
<root>
<data name="ErrorMessage">
<value>There was an error completing this action. Please try again.</value>
</data>
<data name="Welcome">
<value>Welcome</value>
</data>
</root>
รหัสต่อไปนี้แสดงวิธีที่สามารถส่งข้อความที่แปลกลับมาในปลั๊กอินเพื่อแสดงข้อความให้กับผู้ใช้ เป็นขั้นตอนการตรวจสอบความถูกต้องล่วงหน้าของเหตุการณ์ Delete
สำหรับเอนทิตี Account
:
protected void ExecutePreValidateAccountDelete(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
int OrgLanguage = RetrieveOrganizationBaseLanguageCode(localContext.OrganizationService);
int UserLanguage = RetrieveUserUILanguageCode(localContext.OrganizationService,
localContext.PluginExecutionContext.InitiatingUserId);
String fallBackResourceFile = "";
switch (OrgLanguage)
{
case 1033:
fallBackResourceFile = "new_localizedStrings.en_US";
break;
case 1041:
fallBackResourceFile = "new_localizedStrings.ja_JP";
break;
case 1031:
fallBackResourceFile = "new_localizedStrings.de_DE";
break;
case 1036:
fallBackResourceFile = "new_localizedStrings.fr_FR";
break;
case 1034:
fallBackResourceFile = "new_localizedStrings.es_ES";
break;
case 1049:
fallBackResourceFile = "new_localizedStrings.ru_RU";
break;
default:
fallBackResourceFile = "new_localizedStrings.en_US";
break;
}
String ResourceFile = "";
switch (UserLanguage)
{
case 1033:
ResourceFile = "new_localizedStrings.en_US";
break;
case 1041:
ResourceFile = "new_localizedStrings.ja_JP";
break;
case 1031:
ResourceFile = "new_localizedStrings.de_DE";
break;
case 1036:
ResourceFile = "new_localizedStrings.fr_FR";
break;
case 1034:
ResourceFile = "new_localizedStrings.es_ES";
break;
case 1049:
ResourceFile = "new_localizedStrings.ru_RU";
break;
default:
ResourceFile = fallBackResourceFile;
break;
}
XmlDocument messages = RetrieveXmlWebResourceByName(localContext, ResourceFile);
String message = RetrieveLocalizedStringFromWebResource(localContext, messages, "ErrorMessage");
throw new InvalidPluginExecutionException(message);
}
protected static int RetrieveOrganizationBaseLanguageCode(IOrganizationService service)
{
QueryExpression organizationEntityQuery = new QueryExpression("organization");
organizationEntityQuery.ColumnSet.AddColumn("languagecode");
EntityCollection organizationEntities = service.RetrieveMultiple(organizationEntityQuery);
return (int)organizationEntities[0].Attributes["languagecode"];
}
protected static int RetrieveUserUILanguageCode(IOrganizationService service, Guid userId)
{
QueryExpression userSettingsQuery = new QueryExpression("usersettings");
userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
EntityCollection userSettings = service.RetrieveMultiple(userSettingsQuery);
if (userSettings.Entities.Count > 0)
{
return (int)userSettings.Entities[0]["uilanguageid"];
}
return 0;
}
protected static XmlDocument RetrieveXmlWebResourceByName(LocalPluginContext context, string webresourceSchemaName)
{
context.TracingService.Trace("Begin:RetrieveXmlWebResourceByName, webresourceSchemaName={0}", webresourceSchemaName);
QueryExpression webresourceQuery = new QueryExpression("webresource");
webresourceQuery.ColumnSet.AddColumn("content");
webresourceQuery.Criteria.AddCondition("name", ConditionOperator.Equal, webresourceSchemaName);
EntityCollection webresources = context.OrganizationService.RetrieveMultiple(webresourceQuery);
context.TracingService.Trace("Webresources Returned from server. Count={0}", webresources.Entities.Count);
if (webresources.Entities.Count > 0)
{
byte[] bytes = Convert.FromBase64String((string)webresources.Entities[0]["content"]);
// The bytes would contain the ByteOrderMask. Encoding.UTF8.GetString() does not remove the BOM.
// Stream Reader auto detects the BOM and removes it on the text
XmlDocument document = new XmlDocument();
document.XmlResolver = null;
using (MemoryStream ms = new MemoryStream(bytes))
{
using (StreamReader sr = new StreamReader(ms))
{
document.Load(sr);
}
}
context.TracingService.Trace("End:RetrieveXmlWebResourceByName , webresourceSchemaName={0}", webresourceSchemaName);
return document;
}
else
{
context.TracingService.Trace("{0} Webresource missing. Reinstall the solution", webresourceSchemaName);
throw new InvalidPluginExecutionException(String.Format("Unable to locate the web resource {0}.", webresourceSchemaName));
return null;
// This line never reached
}
}
protected static string RetrieveLocalizedStringFromWebResource(LocalPluginContext context, XmlDocument resource, string resourceId)
{
XmlNode valueNode = resource.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "./root/data[@name='{0}']/value", resourceId));
if (valueNode != null)
{
return valueNode.InnerText;
}
else
{
context.TracingService.Trace("No Node Found for {0} ", resourceId);
throw new InvalidPluginExecutionException(String.Format("ResourceID {0} was not found.", resourceId));
}
}