2010-04-05 20 views
6

Çalışıyor, ama nasıl ???Asp.net MVC, geri bildirim sırasında yanlış değerlerimi nasıl hatırlıyor?

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Person person) 
{ 
    bool isvalid = ModelState.IsValid; 
    etc. 

Kişi nesnesi bir özellik doğum tarihi, tip DateTime vardır:

Bir yazı için bir kontrolör eylemi var. Formda bazı geçersiz veriler girdiğimde, geçerli bir Datetime olmadığı açıkça görülen 'blabla' deyin, tüm (diğer) Kişi özelliklerini doğru verilerle ve BirthDate özelliğini yeni bir boş DateTime ile doldurur. Boole geçersiz 'false' değerine sahiptir. Şimdiye kadar çok iyi. Sonra

bunu yapmak:

return View(p); 

ve görünümde ben bu vardır:

<%= Html.TextBox("BirthDate", String.Format("{0:g}", Model.BirthDate)) %> 
<%= Html.ValidationMessage("BirthDate", "*") %> 

Ant orada geliyor: ben değil çünkü ben yeni, boş DateTime içermesi modeli BEKLENEN Herhangi bir yeni veri koyma. İkinci olarak, Görünüm bir şey görüntülediğinde, bir DateTime olmalıdır, çünkü Model.BirthDate bir DateTime dışında hiçbir şey tutamaz. Ama benim için sürpriz, 'blabla' değeri ile bir metin kutusu gösterir! (ve arkasındaki kırmızı *)

Kullanıcı, yanlış yazdıklarını görebileceği için hangisi güzeldir, ancak bu (blabla) dizesi, DateTime alanında View'a nasıl aktarılır?

DÜZENLEME: ModelState bilgileri burada bana çok yardımcı . Ayrıca MVC 2'de, sen Html.EditorFor() için kendi Şablon oluştururken sahip olduğunu bu davranışı kendini uygulamak olduğunu fark eder. I/görünümler/paylaşımlı/EditorTemplates klasöründe bir

DateTime.ascx 

oluşturulur ve bu tesis değeri için ModelState hatası olup olmadığını orada ben kontrol etmek vardı ve eğer öyleyse, yerine geçersiz veri göstermek Model verileri.

Yani görünümünde ben bu kullanın:

<% 
bool invalidData = false; 
string propertyName = ViewData.ModelMetadata.PropertyName; 

ModelState ms = ViewData.ModelState[propertyName]; 
if (ms != null) 
{ 
    invalidData = ms.Errors.Count > 0; 
} 
string valueToshow = invalidData ? ViewData.ModelState[propertyName].Value.AttemptedValue : String.Format("{0:g}", Model); 
%> 
<input class="text-box single-line" id="<%= propertyName %>" name="<%= propertyName %>" type="text" value="<%= valueToshow %>" /> 

cevap

10

ModelState anahtar alanı ismi olması sayesinde her form öğesi için KeyValuePairs tutan:

<%= Html.LabelFor(model => model.DateOfBirth) %> 

ve DateTime.ascx içinde

ben bu kullanmak ve değer, alana koyduğunuz şeydir. Ardından, HTML Yardımcıları ModelState'e bakarlar ve açık bir değer belirtmezseniz, değeri ModelState'den alırlar.

+0

Teşekkürler, şimdi yardımcıların daha sonra modeldeki değeri ayrıştırmak yapmadı. Cevabınız için – Michel

4

Önceden girilen değer ModelState'de saklanır. Formda bir hata olduğunda, yardımcı, Modelden veya özellikle sağlananlardan birini kullanmak yerine ModelState'den değer çeker (başlık altında, eğer açık bir değer sağlamazsanız, modele varsayılan olarak gelir) Hata yok ise bir değer varsa).

+0

+1, Keith biraz daha hızlıydı, umarım cevabını – Michel

+0

olarak işaretlemekten çekinme Bu cevabın doğru olduğunu ve Keith'in tam olarak doğru olmadığını düşünüyorum. Keith'in cevabı, açık bir şekilde bir değer belirtmezseniz ModelState'in kullanıldığını belirtir; Bu cevap, bir hata varsa, bir değerin açıkça belirtilip belirtilmediğine bakılmaksızın, ModelState'in kullanıldığını belirtir. Model Hatası varken POST denetleyicisinden sonra GET denetleyicisini çağırmak için kullanılan model, yalnızca ModelState görüntüleme verileri GET denetleyicide kodladığınız her şeyi geçersiz kıldığı için çalışır. Ekleme için –

1

Geçersiz tanıtım kodlarını kaldıracak ve yanıtı artıracak bir kod 'geri gönderme' vardı. Modeli yeni değerle güncellemeniz durumunda bile, ModelState değeri öncelikli olduğundan (diğerlerinin zaten yanıtladığı gibi) görüntülenmeyecektir.

<%= Html.TextBox("PromoCode", Model.PromoCodes) %> 

Ama bu bittiğini bir durum var ve eski değer bunu yapmak gerek kalıcı istemiyorsanız: muhtemelen (

ModelState.Remove("PromoCode"); 

veya açıkça ModelState yeni değeri ayarlayın Daha iyi yaklaşım):

ModelState.SetModelValue("PromoCode", 
     new ValueProviderResult(newValue, newValue, CultureInfo.CurrentCulture)); 
+0

+1. – Michel