Aplikasi Web Zoo-Blog
Asp Net.Core Aplikasi Web MVC Menggunakan MSSQL EF6 Identity dan Boostrap
Halaman katalog utama tempat Anda dapat menggulir dan memilih animel untuk dijelajahi dan dikomentari

Tentang
Aplikasi Web ASP.NetCore ini menunjukkan pola MVC dengan satu tampilan tata letak berisi batang nav dan renderend body dengan tampilan dan pengontrol yang berbeda. Saya menyertakan satu komponen tampilan untuk membuat animel mengeksplorasi div yang lebih umum antara halaman dan ditata menggunakan boostrap libary
Model (inti framwork entitas)
Diagram MSSQL

Model saya berisi 3 objek: kategori, hewan, dan komentar. Saya memberi masing -masing dari mereka beberapa propetri dan atribut validasi pemasangan termasuk pola regex, kesalahan data kustom tipe kustom dll. Saya membuat dua atribut vlidasi khusus:
- Tanggal lahir untuk memvalidasi hewan kurang dari 150 tahun dan lahir di hari ini atau lebih awal
- Validator File Untuk memeriksa apakah jenis konten file menyertakan kata "gambar" dan ukuran file dibatasi hingga 10MB
| Kelas Publik ImagefileValidationAttribute : ValidationAttribute |
| { |
| const int max_file_size = 10 * 1024 * 1024 ; // 10MB |
| ValidationResult override yang dilindungi ? IsValid ( Object ? Value , ValidationContext ValidationContext ) |
| { |
| if ( nilai adalah file iformFile ! = default ) |
| { |
| if ( file . length > max_file_size ) |
| return new ValidationResult ( "Ukuran file ini lebih besar dari batasan 10MB" ) ; |
| if ( file . contentType . berisi ( "gambar" ) ) |
| Validasi Pengembalian Hasil . Kesuksesan ; |
| return new ValidationResult ( "Ini bukan file yang valid" ) ; |
| } |
| return new ValidationResult ( "Harap masukkan file gambar yang valid" ) ; |
| } |
| } |
Untuk menghasilkan kategori saya membuat model helper enum yang tidak dipetakan ke database tetapi saya menggunakan untuk menghasilkan tag pilih aprested
Proyek Model juga berisi Kelas Repsoitori Basis Lapisan Akses Data Generik untuk setiap entitas yang ID dari tipe GUID dan satu layanan format gambar yang membantu saya menyimpan file gambar sebagai array byte dan menghasilkan gambar kembali di sisi klien
| Byte statis publik [ ] FormFiletobyTeArray ( FormFile FormFile ) |
| { |
| if ( formfile ! = null ) |
| { |
| MemoryStream MemoryStream = New MemoryStream ( ) ; |
| Formfile . OpenReadStream ( ) . Copyto ( Memorystream ) ; |
| byte [ ] rawData = memorystream . Toarray ( ) ; |
| mengembalikan RawData ; |
| } |
| mengembalikan default ; |
| } |
| format string statis publicrawdatoImage ( byte [ ] firficsfiledata ) |
| { |
| if ( ificsfiledata ! = null ) |
| return "Data: Image; Base64," + Convert . Tobase64String ( ImagesFiledata ) ; |
| mengembalikan default ; |
| } |
| |
| } |
Melihat
Saya telah membuat beberapa tampilan untuk pengontrol, satu komponen tampilan dan 3 tampilan parsial useFull untuk gaya tata letak dan skrip dan bilah nav bilah nav digunakan untuk menavigasi antara tampilan dan tindakan yang berbeda
Bilah Nav Aplikasi

Tampilan Manajer Buat dan Pembaruan berisi validasi Vannila JS dari jenis file dan ukurannya untuk mencegah browser untuk melempar kesalahan
| fileInput . addeventListener ( "ubah" , function ( ) { |
| Biarkan filessize = ini . file [ 0 ] . ukuran ; |
| if ( this . file [ 0 ] === tidak terdefinisi || fileSize === tidak terdefinisi ) { |
| ini . setCustomValidity ( "Harap masukkan file" ) ; |
| ini . ReportValidity ( ) ; |
| kembali ; |
| } |
| if ( filessize > maxfileSize ) { |
| ini . setCustomValidity ( "File ini lebih besar dari 10MB" ) ; |
| ini . nilai = "" ; |
| ini . ReportValidity ( ) ; |
| kembali ; |
| } |
| if ( ! ValidFileType ( ini . File [ 0 ] ) ) { |
| ini . setCustomValidity ( "Ini bukan file gambar" ) ; |
| ini . nilai = "" ; |
| ini . ReportValidity ( ) ; |
| kembali ; |
| } |
| if ( filessize < maxfileSize ) { |
| ini . setCustomValidity ( "" ) ; |
| ini . ReportValidity ( ) ; |
| } |
| } ) ; |
Pengontrol
Proyek ini berisi 4 pengontrol:
- Beranda - Menampilkan dua hewan yang paling banyak dikomentari
- Manajer - Menangani Operasi Crud pada Data Hewan
- Katalog - Lihat hewan di blog dan dapat mengurutkannya berdasarkan kategori
- Animel Data - Jelajahi detail hewan dan memungkinkan pengguna untuk meninggalkan komentar. Posting komentar menggunakan API fetch untuk mencegah halaman untuk melakukan relload setiap kali pengguna memposting komentar.
| addComment fungsi async ( event ) { |
| Biarkan komentar = { |
| CommentId : Tidak ditentukan , |
| Konten : ContentTextArea . nilai , |
| Animelid : id , |
| } |
| Komentar = json . Stringify ( komentar ) ; |
| Await fetch ( ` $ { baseUrl } /index` , { |
| Metode : 'Posting' , |
| Tubuh : Komentar , |
| header : { |
| "tipe konten" : "Aplikasi/JSON" |
| } |
| } ) . kemudian ( ( ) => { getAllComments ( ) ; } ) ; |
| } |
Halo komentar dunia

Otentikasi && otorisasi (identitas)
Saya menggunakan identitas nuget dan konteks terpisah untuk mengotentikasi dan mengotorisasi pengguna dalam aplikasi web saya dan mendaftar dan masuk ke handels oleh pembantu model bernama LoginModel dan SignUpmodel di aplikasi ada 3 jenis pengguna "admin", "pengguna" dan anonim. Peran manajer dapat menggunakan pengontrol manajer dan memiliki jangkar nav-link untuk pembuatan dan pembaruan. Setiap pengguna yang ditandatangani dapat mengomentari hewan dalam aplikasi (termasuk manajer). Pengguna anonim hanya dapat menggulir halaman katalog Animels atau mendaftar/masuk.
Tindakan Mendaftar:
| [ Httppost ] |
| [ ValidateAntiForgerToken ] |
| Tugas Async Publik <IactionResult> Register ( Pengguna Masuk ) |
| { |
| if ( modelstate . isValid ) |
| { |
| IdentityUser IDUSER = IDentityUser baru |
| { |
| Nama pengguna = pengguna . Nama belakang , |
| Phonenumber = pengguna . Bilangan fonen , |
| Email = pengguna . E-mail |
| } ; |
| var createresult = menunggu _UserManager . Createasync ( IDUSER , USER . Kata sandi ) ; |
| var addrole = menunggu _UserManager . Addtoroleasync ( idUser , "user" ) ; |
| if ( createresult . berhasil ) |
| { |
| var SignupResult = menunggu _signinManager . PasswordSignInAsync ( pengguna . Nama pengguna , pengguna . Kata sandi , false , false ) ; |
| if ( Signupresult . |
| { |
| return redirecttoaction ( "index" , "home" ) ; |
| } |
| return login ( ) ; |
| } |
| } |
| return view ( ) ; |
| } |
Pengujian unit
Solusi aplikasi web ini mencakup satu proyek pengujian Xunit untuk memeriksa lapisan repositori dan memvalidasi kelas RepoSiroeyBase untuk metode sinkronisasi dan async.
Contoh tes:
| [ Tes , perlu dibaca ] |
| public void findbyidasync ( ) |
| { |
| _CategoryRepository ? . Create ( CategoryTest ! ) ; |
| _animelrepository ? . Buat ( animeltest ! ) ; |
| _commentRepository ? . Buat ( CommentTest ! ) ; |
| |
| Tugas < En Animal > animelfound = _animelrepository ! . Findbyidasync ( animeltest ! . id ) ; |
| animelfound . Continuewith ( _ => { Assert . Itu ( animelfound . Hasil , adalah . Equalto ( animeltest ) ) ; } ) ; |
| Tugas < Ent animal > animelnotfound = _animelrepository . Findbyidasync ( do_not_insret_animel ! . id ) ; |
| animelnotfound . Continuewith ( _ => { assert . Itu ( animelfound . Hasilnya , adalah . Null ) ; } ) ; |
| Tugas <OMMENT> COMMENTFOUND = _CommentRepository ! . FindByidasync ( komentar ! . CommentId ) ; |
| Komentar . Continuewith ( _ => { Assert . Itu ( CommentFound . Hasil , adalah . Equalto ( CommentTest ) ) ; } ) ; |
| Tugas <Gategory> CategoryFound = _CategoryRepository ! . FindByidasync ( CategoryTest ! . CategoryID ) ; |
| kategoriFound . Continuewith ( _ => { Assert . Itu ( CategoryFound . Hasil , adalah . Equalto ( CategoryTest ) ) ; } ) ; |
| } |