NullReferenceException dan melihat properti navigasi model

Saya kesulitan menemukan cara untuk menangani nilai nol dalam model tampilan saya. Beberapa dari nilai ini adalah objek bersarang atau navigasi dalam model saya. Bagaimana cara menjaga pandangan saya agar tidak memunculkan kesalahan referensi nol tanpa memasukkan logika ke dalam tampilan? Ini tampaknya mudah tetapi ini adalah akhir dari segalanya.

Saya memiliki model tampilan dengan beberapa properti navigasi seperti:

LihatModel.cs

public class ViewModel
{
  public ViewModel () {}
  public ViewModel (Contact contact, IDemographicService demographicService)
         : this()
  {
    Id = contact.Id;
    Name = contact.Name;
    EthnicityId = contact.EthnicityId;
    if(EthnicityId > 0 || EthnicityId != null)
       Ethnicity = deomographicService.GetEthnicityById((int)contact.EthnicityId);
  }
  public int Id {get;set;}
  public string Name {get;set;}
  public int? EthnicityId {get;set;}
  public Ethnicity Ethnicity {get;set;}
}

Saya akan melewatkan pengontrol karena itu bukan fokus pertanyaan saya. (Saya tahu bahwa logikanya bisa masuk ke pengontrol tetapi saya memilih untuk memasukkannya ke dalam ViewModel).

Tampilan Saya.cshtml

@model ViewModel
<ul>
<li>@Model.Name</li>
<li>@Model.Ethnicity.Name</>//This is the null reference.
</ul>

Saya kira saya hanya dapat mendefinisikan string "EthnicityName" (dan jika null mengembalikan null) alih-alih seluruh objek tetapi ada beberapa contoh di mana saya memerlukan lebih dari satu properti dari objek Ethnicity. Ini menghilangkan Etnisitas, baik itu dalam model tampilan, pengontrol, atau tampilan. Singkatnya, apa yang harus saya lakukan terhadap null.null? Bingung. Terima kasih.


person trevorc    schedule 05.03.2011    source sumber


Jawaban (3)


Menurut saya, menambahkan "logika" untuk memahami nilai nol bukanlah hal yang buruk. Logika tersebut adalah bagian dari model objek .NET yang mendasarinya; itu bukan logika bisnis.

Namun, Anda tetap dapat menambahkan satu properti ke model untuk setiap properti tipe Ethnicity yang ingin Anda tampilkan di model:

public Ethnicity Ethnicity {get;set;}
public string EthnicityName {
    get {return Ethnicity == null ? String.Empty : Ethnicity.Name;}
    set {if (Ethnicity != null) {Ethnicity.Name = value;}}
}
public int EthnicityCode {
    get {return Ethnicity == null ? 0 : Ethnicity.Code;}
    set {if (Ethnicity != null) {Ethnicity.Code = value;}}
}

Maka pandangan tersebut tidak ada pekerjaan yang harus dilakukan sama sekali.

Perhatikan bahwa menurut saya delegasi semacam ini tidak masalah, dibandingkan dengan pemformatan. Saya tidak akan pernah menambahkan properti ke model yang hanya untuk tujuan pemformatan.

person John Saunders    schedule 05.03.2011
comment
Terima kasih John. Jawaban Anda sejalan dengan apa yang saya pikir harus saya lakukan. Meskipun contoh saya cukup sederhana, proyek saya mencakup objek 'bersarang' lainnya yang memiliki sejumlah besar properti sehingga pendefinisian setiap properti akan menggagalkan tujuan model tampilan. Dalam contoh seperti ini, apakah pernyataan else yang membuat objek kosong akan menjadi verboten? yaitu else LargeObject = new LargeObject(); Dengan cara ini pandangan saya yang memiliki @Model.LargeObject.Property tidak akan menghasilkan nilai nol. Saya benci null, tapi saya terpaksa menghadapinya. - person trevorc; 05.03.2011
comment
hal. Maksud saya logika dalam pandangan - person trevorc; 05.03.2011
comment
@name: Saya bukan ahli MVC, meskipun saya memiliki gambaran umum tentang pemisahan masalah. Saya rasa ini bukan merupakan kekhawatiran tersendiri. Saya akan mengajukan pertanyaan mengapa saya memiliki nilai nol itu - apa semantiknya? Apa yang mereka wakili dalam model? - person John Saunders; 07.03.2011

Sepertinya masalah desain kelas, bukan masalah Tampilan/Model. Anda memiliki kelas yang menyatakan bahwa kelas tersebut akan memberikan Etnisitas sebagai bagian dari status abadi setelah inisialisasi. Namun, saat Anda benar-benar membuat objek, Anda tidak memberikan jaminan tersebut bagi konsumen kelas tersebut. Saya pikir solusi @John Saunders dapat dilakukan, tetapi saya akan lebih bersedia untuk membuat instance instance Default Ethnicity sebagai anggota statis pada tipe Ethnicity dan mengembalikannya. Properti Nama default itu akan mengembalikan jawaban yang sesuai bahasa untuk "Tidak Ada Disediakan" atau sesuatu seperti itu.

person Ritch Melton    schedule 05.03.2011
comment
Ritch Saya mengerti apa yang Anda katakan dan itu adalah sesuatu yang saya pertimbangkan tetapi kenyataan dari proyek saya (contoh saya sederhana untuk diposkan) adalah bahwa saya memiliki grafik objek besar yang sayangnya BISA nol. Klaim layanan kesehatan bertemu dengan penulis hibah dan memutuskan bahwa proyek percontohan kesehatan masyarakat saudaranya lebih baik. - person trevorc; 05.03.2011
comment
Membedakan antara null dan Kosong adalah perilaku model. - person Ritch Melton; 05.03.2011
comment
Namun berdasarkan contoh saya, Etnisitas tidak kosong, melainkan nol. Saya tidak dapat mengontrol jika pengguna tidak memilih etnis. Oleh karena itu Etnisitas.Nama == null.null. Jawaban John di atas menyelesaikan masalah ini kecuali Anda memiliki objek besar dengan banyak properti. - person trevorc; 05.03.2011
comment
Itu memang menyelesaikannya, tetapi itu menciptakan ketergantungan pada ViewModel untuk setiap properti di kelas Etnisitas. Bayangkan jika Anda memiliki 50, atau 100 properti untuk diteruskan dengan cara itu. Bagaimana jika Anda mengubah tipe salah satu Properties. Kopling seperti itu tidak perlu dan membuat segalanya menjadi rapuh. Saya akan menambahkan contoh, tetapi Anda tampak senang dengan tanggapan @ John, jadi saya biarkan saja. - person Ritch Melton; 05.03.2011
comment
Saya rasa saya tidak bisa menjelaskan diri saya dengan baik. Komentar terakhir Anda menggambarkan dengan tepat kesulitan saya yang sebenarnya. Saya setuju 100% dengan apa yang Anda katakan tentang 50 atau 100 properti. Saya kira pertanyaan saya adalah: Jika Etnis memiliki 50 properti yang mungkin dilihat atau tidak (@Model.Ethnicity.Property1, dll.) dalam tampilan? Lalu apakah pernyataan if/else yang membuat objek Etnisitas kosong untuk memenuhi pandangan merupakan praktik yang buruk? Itulah satu-satunya solusi yang dapat saya pikirkan tanpa jawaban John dan ketergantungan yang Anda jelaskan. - person trevorc; 05.03.2011
comment
Tidak, if/else bukanlah praktik yang buruk. saat membuat VM, jika pembacaan dalam etnisitas adalah nol, tetapkan properti Etnis VM ke Etnis. Kosong adalah solusi yang saya rekomendasikan. - person Ritch Melton; 05.03.2011

Anda mungkin tertarik untuk mengimplementasikan antarmuka IDataErrorInfo di ViewModel Anda, oleh karena itu terapkan logika validasi di sana, bukan langsung di pengambil/penyetel properti.

person Nano Taboada    schedule 11.04.2011