การแก้ไขปัญหาข้อผิดพลาด "สถานะมุมมองไม่ถูกต้อง" กับ ASP.NET

สรุป

บทความนี้อธิบายเทคนิคบางอย่างที่สามารถใช้ เพื่อดีบัก และเมื่อต้อง การแก้ไขปัญหาเกี่ยวกับสถานะของมุมมองในโปรแกรมประยุกต์ Microsoft ASP.NET

บทนำ

ดูสถานะคือ คุณลักษณะใน ASP.NET ที่ช่วยให้หน้าเพื่อจะทำรักษาสถานะได้โดยไม่ต้องพึ่งพาสถานะเซิร์ฟเวอร์ (ตัวอย่างเช่น สถานะเซสชัน) อย่างไรก็ตาม การตัดสินค้าจากคลังที่เกี่ยวข้องเพื่อดูสถานะอาจเป็นเรื่องยากเมื่อต้องการตรวจแก้จุดบกพร่อง ในกรณีส่วนใหญ่ เมื่อเกิดปัญหาเกี่ยวกับการดูสถานะ คุณได้รับข้อความแสดงข้อผิดพลาดดังต่อไปนี้ในเว็บเบราว์เซอร์ กับการบ่งชี้ของสิ่งที่อาจก่อให้เกิดปัญหาเล็กน้อย:
"Viewstate ไม่ถูกต้องสำหรับเพจนี้ และอาจจะเสียหาย"
บทความนี้อธิบายเทคนิคบางอย่างที่สามารถใช้ สำหรับการดีบัก และ การแก้ไขปัญหาเกี่ยวกับการดูสถานะ

ข้อมูลเพิ่มเติม

ตรวจสอบว่า คุณไม่ได้ทำงานเป็นการตัดสินค้าจากคลังที่ได้รับการแก้ไข

ตัวเลขของสถานะของมุมมองที่ได้รับการแก้ไขปัญหากับ ASP.NET 1.0 ฮอตฟิกซ์ และเซอร์วิสแพ็ค และการแก้ไขปัญหาเหล่านั้นจะเป็นส่วนหนึ่งของ ASP.NET 1.1 ตรวจสอบให้แน่ใจว่า คุณได้ใช้การแก้ไขปัญหาล่าสุดก่อนที่จะติดตามการตัดสินค้าจากคลังที่ได้รับการแก้ปัญหา คุณสามารถขอรับโปรแกรมปรับปรุง Microsoft .NET Framework รุ่นล่าสุดจากเว็บไซต์ Microsoft Developer Network (MSDN) ต่อไปนี้:

ตั้งค่าแอตทริบิวต์ validationKey ถ้าคุณกำลังเรียกใช้ในฟาร์มเว็บ

ในฟาร์มเว็บ แต่ละคำร้องขอของไคลเอ็นต์สามารถไปยังเครื่องอื่นบนทุก ๆ หนึ่งการส่งคืน เนื่องจากพฤติกรรมนี้ คุณไม่สามารถปล่อยให้แอตทริบิวต์validationKeyเพื่อสร้างการตั้งค่าในแฟ้ม Machine.config แทน คุณต้องตั้งค่าของแอตทริบิวต์validationKeyให้เป็นสตริถาวรที่ใช้ร่วมกัน โดยเครื่องจักรทั้งหมดในฟาร์มเว็บ

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับปัญหานี้ คลิกที่หมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

323744แก้ไข: ข้อผิดพลาด "สถานะมุมมองไม่ถูกต้องสำหรับเพจนี้ และอาจจะเสีย" ใน ASP.NET

จัดเก็บชนิดที่สร้างขึ้นแบบไดนามิกในมุมมองรัฐในฟาร์มเว็บ

เมื่อ ASP.NET คอมไพล์แฟ้มแบบไดนามิก แฟ้มที่มีอยู่แล้วภายในแอสเซมบลีด้วยชื่อที่สุ่มและจำเป็นอย่างยิ่ง (ตัวอย่าง ชื่อแฟ้มอาจเป็น jp395dun.dll) ได้ ถ้าคุณกำลังทำงานอยู่ในฟาร์มเว็บ แฟ้มเดียวกันจะถูกคอมไพล์ไว้ในแอสเซมบลีด้วยชื่อที่สุ่มแตกต่างกัน โดยปกติ ไม่มีปัญหาได้เนื่องจากไม่มีผู้ใดทำให้สมมติฐานเกี่ยวกับชื่อแอสเซมบลีเหล่านั้น แต่ถ้าคุณเคยใส่ชนิดคอมไพล์แบบไดนามิกเข้าสู่สถานะมุมมอง โดยใช้การจัดเรียงแบบอนุกรมไบนารี ชื่อของแอสเซมบลีจะถูกรวมเป็นส่วนหนึ่งของข้อมูลสถานะมุมมอง เมื่อที่ดู สถานะเป็นรุ่นที่ใหม่กว่าถูกส่งไปยังเซิร์ฟเวอร์อื่นในฟาร์มเว็บ สถานะมุมมองไม่สามารถ deserialized ได้เนื่องจากมีใช้ชื่อแอสเซมบลีที่แตกต่างกัน

ปัญหานี้การแก้ไขดีที่สุดเพื่อ หลีกเลี่ยงการทำให้เป็นอนุกรมแบบไบนารีที่ใช้อยู่ ทำให้เป็นอนุกรมแบบไบนารีใช้ทรัพยากรมากแม้ว่าคุณไม่ได้รันเป็นปัญหานี้ แทน จำกัดสิ่งที่คุณใส่ในมุมมองรัฐเป็นการรวมกันของอาร์เรย์คู่ Tripletsและชนิดแบบธรรมดา (ตัวอย่างสตริง intและชนิดอื่น ๆ) System.Web.UI.PairและSystem.Web.UI.Tripletมีชนิดแบบธรรมดา wrapper ที่กลไกจัดการสถานะมุมมองสามารถประมวลผลได้อย่างมีประสิทธิภาพ

การแก้ไขอื่นเพื่อหลีกเลี่ยงปัญหานี้คือการ ย้ายชนิดว่า คุณจะจัดเก็บในมุมมองสถานะเป็นไพล์แอสเซมบลีที่ ในโฟลเดอร์ของช่องเก็บ หรือ ในแค ชของแอสเซมบลีส่วนกลาง การแก้ไขนี้ไม่ได้กล่าวประสิทธิภาพ แต่ก็รับรองว่า แอสเซมบลีที่มีชื่อเดียวกันในคอมพิวเตอร์ทั้งหมด

หมายเหตุ ถ้าคุณเก็บชนิดข้อมูลที่ซับซ้อนในมุมมองรัฐประสบปัญหานี้ ข้อมูลสแตกการเรียกจะประกอบด้วยไพ่ที่มีลักษณะคล้ายกับต่อไปนี้:
[FileNotFoundException: Could not load file or assembly 'App_Web_fx--sar9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.] System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +0
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +72
System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +58
System.Type.GetType(String typeName, Boolean throwOnError) +57
System.Web.UI.ObjectStateFormatter.DeserializeType(SerializerBinaryReader reader) +192
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +943
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +384
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +198
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +210
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +198
System.Web.UI.ObjectStateFormatter.Deserialize(Stream inputStream) +142

ตรวจสอบว่า ปัญหาเกี่ยวข้องกับคุณลักษณะมุมมองสถานะ MAC

วัตถุประสงค์ของมุมมองสถานะเครื่องจักรรับรองความถูกต้อง (MAC) ของรหัสลักษณะการทำงานจะทำให้ไม่สำหรับไคลเอนต์ส่งการร้องขอที่ประกอบด้วยสถานะเป็นมุมมองที่เป็นอันตราย โดยค่าเริ่มต้น คุณลักษณะนี้ถูกเปิดใช้งานในค่าสถานะต่อไปนี้ในแฟ้ม Machine.config
enableViewStateMac="true"
วิธีง่ายที่สุดเพื่อตรวจสอบว่า คุณกำลังเผชิญกับการตัดสินค้าจากคลังเกี่ยวข้องกับลักษณะการทำงานของ MAC เมื่อต้องการปิดคุณลักษณะนี้ได้ เมื่อต้องการทำเช่นนี้ เปลี่ยนค่าสถานะในแฟ้ม Machine.config กับรหัสต่อไปนี้
enableViewStateMac="false"
ถ้าคุณไม่ได้รับข้อผิดพลาดสถานะมุมมอง ปัญหาเกี่ยวข้องกับลักษณะการทำงานของ MAC

สิ่งสำคัญ ปิดคุณลักษณะการ MAC สถานะมุมมองเพื่อช่วยวินิจฉัยปัญหาเฉพาะ คุณไม่ควรเก็บสถานะมุมมอง MAC ปิดเพื่อหลีกเลี่ยงปัญหานี้ ถ้าเป็นเช่นนั้น คุณไม่สามารถนำช่องโหว่ความปลอดภัย สำหรับข้อมูลเพิ่มเติม โปรดเยี่ยมชมเว็บไซต์ต่อไปนี้:ถ้าคุณปิดใช้งานคุณลักษณะมุมมองสถานะ MAC และจากนั้น คุณใช้ มุมมองสถานะสำหรับตัวควบคุมที่ทำ HTML ไม่ได้เข้ารหัส (เช่น ตัวควบคุมป้ายชื่อ) ผู้โจมตีสามารถเข้ามายุ่งกับข้อมูลสถานะมุมมอง และสามารถเก็บข้อมูลที่กำหนดที่รัฐในมุมมอง ข้อมูลนี้กำหนดถูกถอดรหัส และจากนั้น ใช้ โดยตัวควบคุมเมื่อพวกเขาแสดงหน้าการลงรายการบัญชีแล้ว ผลที่ได้ ผู้โจมตีสามารถใส่สคริปต์ลงในแอพลิเคชันยกเว้นว่าคุณทำงานเพื่อป้องกันการโจมตี ตัวอย่างเช่น โจมตีไม่สามารถถอดรหัสข้อมูล ใส่สคริปต์ลงในข้อมูลที่เป็นตัวควบคุมป้ายชื่อและจากนั้นเชื่อมโยงมาจากเว็บไซต์ ใครก็ตามที่คุณคลิกที่การเชื่อมโยงอาจเป็นเหยื่อของการโจมตีใส่สคริปต์ที่อาจไม่สามารถขโมยคุกกี้การรับรองความถูกต้องหรือรหัสรอบเวลาของตนเอง ยังให้สคริปต์การโจมตีที่มีเปลี่ยนข้อมูลสถานะสำหรับตัวควบคุมที่ใช้สถานะมุมมอง และโจมตีเฉพาะแอพลิเคชันไม่สามารถเกิดขึ้นได้ดังนั้น

โดยทั่วไป Microsoft แนะนำว่า คุณไม่ปิดใช้งานมุมมองสถานะ MAC คุณลักษณะเว้นแต่คุณจะเชื่อถือว่า คุณมีสถานะอย่างใดอย่างหนึ่งมุมมองที่ถูกปิดใช้งานสำหรับตัวควบคุมทั้งหมดที่ทำ HTML ไม่เข้ารหัสผลลัพธ์ของตนเอง (ตัวอย่างเช่น ตัวควบคุมDataGrid , DataListควบคุม ตัวควบคุมป้ายชื่อและตัวควบคุมอื่น ๆ) หรือว่า ได้ชัดเจนเสมอคุณกำลังตั้งค่าบนแต่ละการร้องขอเพื่อบางสิ่งบางอย่างที่ปลอดภัย

สำหรับข้อมูลเพิ่มเติม คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

316920คุณได้รับข้อความแสดงข้อผิดพลาด "สถานะมุมมองไม่ถูกต้อง" เมื่อคุณใช้เมธอด Server.Transfer

รับรองความถูกต้องของฟอร์มและมุมมองสถานะล้มเหลวเป็นระยะ ๆ อัปโหลด324488

ตรวจสอบแน่นอนใดข้อยกเว้นเกิดขึ้นเมื่อคุณได้รับข้อความแสดงข้อผิดพลาด

แต่ ข้อผิดพลาดสถานะมุมมองไม่ถูกต้องที่ระบุไว้ในส่วน "บทนำ" ของบทความนี้ ไม่ใช่ข้อมูลมากขึ้น ข้อความแสดงข้อผิดพลาดที่เกิดจากข้อยกเว้นบางอย่างจะเกิดขึ้นเมื่อกำลังประมวลผลมุมมองสถานะโดยทั่วไป ปัญหาคือ ข้อยกเว้นการใช้ และรายละเอียดหายไปในข้อความข้อผิดพลาด

โดยการใช้ดีบักเกอร์ คุณสามารถกำหนดข้อยกเว้นที่เดิม เมื่อต้องการทำเช่นนี้ คุณต้องแนบดีบักเกอร์กับกระบวนการ ASP.NET (Aspnet_wp.exe หรือ W3wp.exe), และตั้งค่าดังกล่าวเพื่อตรวจจับทั้งหมดยกเว้น ดีบักเกอร์จะหยุดการที่สองสามข้อยกเว้นที่ไม่เกี่ยวข้องอาจ แต่ในขั้นสุดท้ายจะดูสถานะข้อยกเว้นการเข้าชม และให้ข้อมูลที่เป็นประโยชน์สำหรับการแก้ไขปัญหา

ขั้นตอนต่อไปนี้เป็นตัวอย่างที่ใช้ดีบักเกอร์รันไทม์ (Cordbg.exe)
  1. ที่พรอมต์คำสั่ง รันนี้
    คำสั่งiisresetเพื่อให้แน่ใจว่า คุณจะมีจุดเริ่มต้นดี และจากนั้น เรียกดูไปยังหน้าบนไซต์ของคุณ
  2. ที่พรอมต์คำสั่ง เรียกใช้
    cordbg.exe.
  3. ที่พรอมต์คำสั่ง พิมพ์ตามและจากนั้น กด ENTER รายการของกระบวนการที่มีการจัดการจะปรากฏขึ้น คุณควรเห็นกระบวนการ Aspnet_wp.exe หรือกระบวนการ W3wp.exe หมายเหตุของหมายเลขผลิตภัณฑ์
  4. ที่พรอมต์ พิมพ์คำ
    หมายเลขผลิตภัณฑ์จะแนบกับกระบวนการ

    หมายเหตุ แทนหมายเลขผลิตภัณฑ์กับหมายเลขผลิตภัณฑ์ที่ถูกบันทึกไว้ในขั้นตอนที่ 3
  5. ที่พรอมต์ พิมพ์อี caเพื่อบอก Cordbg.exe เพื่อหยุดในข้อยกเว้นทั้งหมด และจากนั้น พิมพ์gเพื่อให้กระบวนการเรียกใช้
  6. เมื่อใดก็ ตามที่คุณได้รับข้อยกเว้น พิมพ์
    wเมื่อต้องการดูจากในกองซ้อน ถ้ากองซ้อน ข้อยกเว้นสถานะมุมมอง (ค้นหา LoadPageStateFromPersistenceMedium ในกองซ้อน), คัดลอกข้อยกเว้นทั้งหมดและข้อมูลสแตกจากหน้าต่างคำสั่ง และจากนั้น บันทึกข้อมูล ข้อมูลนี้สามารถช่วยให้คุณเข้าใจปัญหา ถ้าข้อยกเว้นที่ไม่เกี่ยวข้อง พิมพ์g
สำหรับข้อมูลเพิ่มเติม ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

831150ข้อผิดพลาด "Viewstate ไม่ถูกต้องสำหรับเพจนี้" ไม่มีข้อมูลเพียงพอที่จะแก้ปัญหาได้

ลองจัดเก็บสถานะมุมมองในเซสชัน

โดยค่าเริ่มต้น ดูรัฐนี้คือ tripped ปัดโดย means ของการ< ป้อนชนิด =ซ่อน >ฟิลด์ที่จะถูกส่งไปยังเบราว์เซอร์ เบราว์เซอร์ส่งฟิลด์กลับไปยังเซิร์ฟเวอร์บนคำขอถัดไปแล้ว ในบางกรณี สถานะมุมมองนี้สามารถรับค่อนข้างใหญ่ และเป็นแหล่งที่เป็นไปได้ของปัญหา เบราว์เซอร์บางตัวไม่สามารถจัดการได้ดังกล่าวมีขนาดใหญ่ที่ซ่อนเขตข้อมูล (และร้องขอผลลัพธ์ขนาดใหญ่), และเบราว์เซอร์ที่อาจตัดทอนสถานะมุมมอง ตัดทอนสถานะมุมมองทำให้ข้อความแสดงข้อผิดพลาด "ดูรัฐที่เสียหาย" ลักษณะการทำงานนี้ไม่น่าจะเกิดขึ้นในเบราว์เซอร์ง่ายกว่า ตัวอย่างเช่น ลักษณะการทำงานนี้อาจเกิดขึ้นในเบราว์เซอร์บนตัว PDA


เมื่อต้องการตรวจสอบว่า คุณอาจสามารถใช้เข้าประเด็นดังกล่าว ลองจัดเก็บสถานะมุมมองในเซสชัน ตัวอย่างต่อไปนี้สาธิตวิธีการทำเช่นนี้
<%@ language=c# debug=true %> 
<script runat=server>
protected override object LoadPageStateFromPersistenceMedium()
{
return Session["_ViewState"];
}

protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session["_ViewState"] = viewState;
}

void TextChanged(object o, EventArgs e)
{
Response.Write("TextChanged");
}
</script>
<form runat=server>
<asp:button text=Test runat=server/>
<asp:textbox ontextchanged=TextChanged runat=server/>
<input type=hidden name=__VIEWSTATE>
</form>


บรรทัดของรหัสต่อไปนี้เท่านั้นใน ASP.NET 1.0 การแก้จุดบกพร่อง ใน ASP.NET 1.1 คุณไม่จำเป็น
<input type=hidden name=__VIEWSTATE>

ตรวจสอบว่า ปัญหาเกิดจากกลับกระบวนการของผู้ปฏิบัติงาน

พิจารณาสถานการณ์สมมติต่อไปนี้
  • คุณกำลังเรียกใช้ภายใต้ Microsoft Internet Information Services (IIS) 6.0 ASP.NET
  • พูลโปรแกรมประยุกต์กำลังทำงานอยู่ภายใต้รหัสประจำตัวอื่นที่ไม่ใช่บัญชี Local System บัญชีบริการเครือข่าย หรือบัญชีผู้ใช้ระดับผู้ดูแลระบบ
  • แอตทริบิวต์validationKeyขององค์ประกอบ < machineKey > ถูกตั้งค่าเป็นการสร้างอัตโนมัติในแฟ้มการกำหนดค่า
ในสถานการณ์สมมตินี้ ขั้นตอนต่อไปนี้จะทำให้การดูสถานะข้อผิดพลาดจะเกิดขึ้น:
  1. ผู้ใช้เรียกดูเพจ
  2. กระบวนการของผู้ปฏิบัติงานที่เป็นโฮสต์ของแอพลิเคชัน ASP.NET recycles
  3. ผู้ใช้ที่ลงรายการบัญชีกลับหน้า
วิธีการแก้ปัญหาสำหรับสถานการณ์สมมตินี้มีการ ใช้แอตทริบิวต์อย่างชัดแจ้งvalidationKeyในแฟ้มการกำหนดค่า
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสร้างคีย์ คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

วิธีการ312906เพื่อสร้างคีย์ โดยใช้ Visual C# .NET สำหรับใช้ในการรับรองความถูกต้องของฟอร์ม

วิธีการ313091เพื่อสร้างคีย์ โดยใช้ Visual Basic .NET สำหรับใช้ในการรับรองความถูกต้องของฟอร์ม

ข้อมูลอ้างอิง

สำหรับข้อมูลเพิ่มเติม คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

316920 "สถานะมุมมองไม่ถูกต้อง" ข้อผิดพลาดเมื่อคุณใช้ Server.Transfer

รับรองความถูกต้องของฟอร์มและมุมมองสถานะล้มเหลวเป็นระยะ ๆ อัปโหลด324488

831150ข้อผิดพลาด "Viewstate ไม่ถูกต้องสำหรับเพจนี้" ไม่มีข้อมูลเพียงพอที่จะแก้ปัญหาได้

สำหรับข้อมูลเพิ่มเติม โปรดเยี่ยมชมเว็บไซต์ต่อไปนี้:
คุณสมบัติ

รหัสบทความ: 829743 - การตรวจสอบครั้งสุดท้าย: 24 ก.พ. 2017 - ฉบับแก้ไข: 1

คำติชม