แอป Zoo-Blog Web
ASP NET.CORE MVC Web App โดยใช้ MSSQL EF6 Identity และ Boostrap
หน้าแคตตาล็อกหลักที่คุณสามารถเลื่อนและเลือก Animel เพื่อสำรวจและแสดงความคิดเห็น

เกี่ยวกับ
แอป ASP.NetCore Web นี้แสดงรูปแบบ MVC ด้วยมุมมองเลย์เอาต์หนึ่งมุมมีแถบ NAV และตัวแสดงที่มีมุมมองและตัวควบคุมที่แตกต่างกัน ฉันรวมองค์ประกอบมุมมองหนึ่งเพื่อให้แอนิเมชั่นสำรวจ divs มากขึ้นระหว่างหน้าและสไตล์โดยใช้ boostrap libary
โมเดล (Entity Framwork Core)
ไดอะแกรม MSSQL

โมเดลของฉันมี 3 วัตถุ: หมวดหมู่สัตว์และความคิดเห็น ฉันให้พวกเขาแต่ละ propetries และคุณลักษณะการตรวจสอบความถูกต้องที่เหมาะสมรวมถึงรูปแบบ regex, ประเภทข้อมูลผิดพลาด Messege ที่กำหนดเอง ฯลฯ .. ฉันสร้างแอตทริบิวต์ Vlidation ที่กำหนดเองสองรายการ:
- วันเกิดเพื่อตรวจสอบสัตว์น้อยกว่า 150 ปีและเกิดในวันปัจจุบันหรือก่อนหน้านี้
- ตัวตรวจสอบไฟล์เพื่อตรวจสอบว่าประเภทเนื้อหาของไฟล์นั้นมีคำว่า "ภาพ" และขนาดของไฟล์ที่ จำกัด ไว้ที่ 10MB
| Public Class ImageFileValidationAttribute : ValidationAttribute |
| - |
| const int max_file_size = 10 * 1024 * 1024 ; // 10MB |
| ได้รับการคุ้มครอง การแทนที่ ValidationResult ? ISVALID ( Object ? value , ValidationContext ValidationContext ) |
| - |
| ถ้า ( ค่า คือ ไฟล์ iformfile ! = ค่าเริ่มต้น ) |
| - |
| if ( ไฟล์ . ความยาว > max_file_size ) |
| ส่งคืน ValidationResult ใหม่ ( "ขนาดของไฟล์นี้ใหญ่กว่าข้อ จำกัด 10MB" ) ; |
| if ( ไฟล์ . contentType . มี ( "image" )) ) |
| ส่ง คืน ValidationResult ความสำเร็จ ; |
| ส่งคืน ValidationResult ใหม่ ( "นี่ไม่ใช่ไฟล์ที่ถูกต้อง" ) ; |
| - |
| ส่งคืน ValidationResult ใหม่ ( "โปรดป้อนไฟล์ภาพที่ถูกต้อง" ) ; |
| - |
| - |
เพื่อสร้างหมวดหมู่ฉันสร้างโมเดลผู้ช่วย Enum ซึ่งไม่ได้แมปเข้ากับฐานข้อมูล แต่ฉันใช้เพื่อสร้างแท็กที่เลือกสรร
โครงการโมเดลยังมีคลาสการเข้าถึงข้อมูลชั้นฐานข้อมูลทั่วไปสำหรับแต่ละเอนทิตีซึ่ง ID เป็นประเภท GUID และบริการหนึ่งรายการของการสร้างภาพซึ่งช่วยให้ฉันบันทึกไฟล์รูปภาพเป็นอาร์เรย์ไบต์และสร้างภาพกลับด้านไคลเอ็นต์
| Public Static Byte [ ] FormFileTobyTearray ( FormFile Formfile ) |
| - |
| if ( formfile ! = null ) |
| - |
| MemoryStream MemoryStream = new MemoryStream ( ) ; |
| ฟอร์ม ไฟล์ OpenReadStream ( ) Copyto ( MemoryStream ) ; |
| Byte [ ] RawData = MemoryStream toarray ( ) ; |
| กลับ Rawdata ; |
| - |
| ส่งคืน ค่าเริ่ม ต้น ; |
| - |
| String String Public FormatRawDatatoImage ( byte [ ] imagesfiledata ) |
| - |
| if ( imagesfiledata ! = null ) |
| ส่งคืน " ข้อมูล: image; base64," + แปลง Tobase64string ( Imagesfiledata ) ; |
| ส่งคืน ค่าเริ่ม ต้น ; |
| - |
| |
| - |
ดู
ฉันได้สร้างมุมมองหลายมุมมองสำหรับคอนโทรลเลอร์องค์ประกอบมุมมองหนึ่งและ 3 มุมมองที่เป็นประโยชน์สำหรับรูปแบบเค้าโครงและสคริปต์และแถบนาวิก
แถบ Nav ของแอพ

มุมมองตัวจัดการของการสร้างและอัปเดตมีการตรวจสอบ Vannila JS ของประเภทไฟล์และขนาดไอทีเพื่อป้องกันไม่ให้เบราว์เซอร์โยนข้อผิดพลาด
| FileInput addeventListener ( "เปลี่ยน" , function ( ) { |
| ให้ filesize = สิ่ง นี้ ไฟล์ [ 0 ] ขนาด ; |
| if ( นี้ . ไฟล์ [ 0 ] === undefined || filesize === undefined ) { |
| นี้ . SetCustomValidity ( "โปรดป้อนไฟล์" ) ; |
| นี้ . ReportValidity ( ) ; |
| กลับ ; |
| - |
| if ( filesize > maxfilesize ) { |
| นี้ . SetCustomValidity ( "ไฟล์นี้มากกว่า 10MB" ) ; |
| นี้ . ค่า = "" ; |
| นี้ . ReportValidity ( ) ; |
| กลับ ; |
| - |
| if ( ! validFileType ( ไฟล์ นี้ . [ 0 ] ) ) { |
| นี้ . SetCustomValidity ( "นี่ไม่ใช่ไฟล์ภาพ" ) ; |
| นี้ . ค่า = "" ; |
| นี้ . ReportValidity ( ) ; |
| กลับ ; |
| - |
| if ( filesize < maxfilesize ) { |
| นี้ . SetCustomValidity ( "" ) ; |
| นี้ . ReportValidity ( ) ; |
| - |
| } ) ; |
ผู้ควบคุม
โครงการนี้มีตัวควบคุม 4 ตัว:
- หน้าแรก - แสดงสัตว์ที่มีความคิดเห็นมากที่สุดสองตัว
- ผู้จัดการ - จัดการการดำเนินการ CRUD บนข้อมูลสัตว์
- แคตตาล็อก - ดูสัตว์ในบล็อกและสามารถจัดเรียงตามหมวดหมู่
- Animel Data - สำรวจรายละเอียดสัตว์และอนุญาตให้ผู้ใช้แสดงความคิดเห็น การโพสต์ความคิดเห็นใช้ FETCH API เพื่อป้องกันไม่ให้หน้าดำเนินการ RELLOAL ทุกครั้งที่ผู้ใช้โพสต์ความคิดเห็น
| ฟังก์ชัน Async addcomment ( เหตุการณ์ ) { |
| ให้ ความคิดเห็น = { |
| ความคิดเห็น ที่ไม่ได้ กำหนด |
| เนื้อหา : ContentTextArea ค่า , |
| animelid : id , |
| - |
| ความ คิดเห็น = JSON Stringify ( ความคิดเห็น ) ; |
| รอ การดึงข้อมูล ( ` $ { baseUrl } /index` , { |
| วิธี : 'โพสต์' , |
| ร่างกาย : ความคิดเห็น , |
| ส่วนหัว : { |
| "ประเภทเนื้อหา" : "แอปพลิเคชัน/json" |
| - |
| } ) ดังนั้น ( ( ) => { getAllComments ( ) ; } ) ; |
| - |
สวัสดีโลกแสดงความคิดเห็น

การรับรองความถูกต้อง && การอนุญาต (ข้อมูลประจำตัว)
ฉันใช้เอกลักษณ์ NuGet และ Seperate บริบทเพื่อตรวจสอบสิทธิ์และอนุญาตให้ผู้ใช้ในเว็บแอปพลิเคชันของฉันและลงทะเบียนและลงทะเบียนใน Handels โดยผู้ช่วยรุ่นชื่อ LoginModel และ SignupModel ในแอพมีผู้ใช้ 3 ประเภท "ผู้ดูแลระบบ" บทบาทของผู้จัดการสามารถใช้คอนโทรลเลอร์ผู้จัดการและมีจุดยึด Nav-Link เพื่อสร้างและอัปเดต ผู้ใช้ที่ลงนามทุกคนสามารถแสดงความคิดเห็นเกี่ยวกับสัตว์ในแอปพลิเคชัน (รวมถึงผู้จัดการ) ผู้ใช้ที่ไม่ระบุชื่อสามารถเลื่อนดูหน้าแคตตาล็อกแอนิเมชั่นหรือลงทะเบียน/เข้าสู่ระบบเท่านั้น
การลงทะเบียนการดำเนินการ:
| [ httppost ] |
| [ ValidateantiforgeryToken ] |
| งาน Async สาธารณะ <IaCtionResult> ลง ทะเบียน ( ผู้ ใช้ SignupModel ) |
| - |
| if ( modelState . isvalid ) |
| - |
| IdentityUser Iduser = ใหม่ identityUser |
| - |
| ชื่อผู้ใช้ = ผู้ ใช้ ชื่อผู้ใช้ , |
| Phonenumber = ผู้ ใช้ Phonenumber |
| อีเมล = ผู้ ใช้ อีเมล |
| } ; |
| var createResult = รอ _userManager createasync ( Iduser ผู้ ใช้ รหัส ผ่าน ) ; |
| var addrole = รอ _userManager AddToroleasync ( Iduser , "ผู้ใช้" ) ; |
| ถ้า ( CreateResult . ประสบความสำเร็จ ) |
| - |
| var signupresult = รอ _signinManager PasswordSigninAsync ( ผู้ ใช้ ชื่อ ผู้ ใช้ ผู้ ใช้ รหัส ผ่าน เท็จ เท็จ ) ; |
| if ( signupresult . สำเร็จ ) |
| - |
| return redirecttoaction ( "ดัชนี" , "home" ) ; |
| - |
| กลับเข้า สู่ระบบ ( ) ; |
| - |
| - |
| Return View ( ) ; |
| - |
การทดสอบหน่วย
โซลูชันเว็บแอปนี้รวมโครงการ XUNIT หนึ่งโครงการของการทดสอบสำหรับการตรวจสอบเลเยอร์ที่เก็บและตรวจสอบคลาส reposiroeybase สำหรับวิธีการซิงค์และ ASYNC
ตัวอย่างทดสอบ:
| [ ทดสอบ , ต้องการการอ่าน ] |
| โมฆะ สาธารณะ FindByidasync ( ) |
| - |
| _categoryRepository ? - สร้าง ( categorytest ! ) ; |
| _animelRepository ? - สร้าง ( animeltest ! ) ; |
| _commentrepository ? - สร้าง ( commenttest ! ) ; |
| |
| งาน <imant> animelfound = _animelRepository ! - FindByidasync ( animeltest !. id ) ; |
| แอนิเมชั่ น Continuewith ( _ = > { ยืนยัน ว่า ( animelfound . ผลลัพธ์ คือ . equalto ( animeltest ) ) ; } ) ; |
| งาน <imant> animelNotFound = _animelRepository findByidasync ( do_not_insret_animel !. id ) ; |
| Animelnotfound Continuewith ( _ = > { ยืนยัน ว่า ( animelfound . ผลลัพธ์ , คือ . null ) ; } ) ; |
| งาน < ความคิดเห็น > commentFound = _commentRepository ! - findByidasync ( comminenttest !. comminentiD ) ; |
| CommentFound Continuewith ( _ = > { ยืนยัน ว่า ( CommentFound . ผลลัพธ์ คือ . equalto ( commentTest ) ) ; } ) ; |
| งาน < S CATEGORY > CATEGORYFOUND = _CategoryRepository ! - FindByidasync ( หมวดหมู่ Test !. categoryID ) ; |
| หมวด หมู่ Continuewith ( _ = > { ยืนยัน ว่า ( categoryfound . ผลลัพธ์ คือ . equalto ( categorytest ) ) ; } ) ; |
| - |