2015-04-08 17 views
5

ASP MVC 4 sitemde garip bir soruna dönüşüyor. Kullanıcı create formunu açar ve veritabanımıza bir ajan eklemeye çalışırsa, ilk olarak sahalarda doğrulamayı doğal olarak çalıştırırız. Bir hata varsa, aracıyı eksik durumda kaydeder ve kullanıcıyı yeniden oluşturma sayfasına yönlendiririz. kullanıcı aracısı yeniden kaydetmeye çalıştığındaRazor, HiddenFor'da gizli PK'yi gizlemeyecek

hata geliyor. İlk geri gönderimde, ajan veritabanına kaydedilir ve bir PK oluşturulur. Ancak, ikinci geri planda, PK, otomatik olarak oluşturulmuş olanın yerine 0 değerine sahip sunucuya gönderiliyor.

Ancak bu 0 her zaman değeriyle vermektedir, Create görünümde HiddenFor ekledik.

Ayrıca .Save çağrıldıktan sonra return View çağrıldığında PK hala mevcut olup, oluşturulan emin olmak için kod boyunca adım ve görünüştür olduğunda Model.ID özelliği aynı değeri içerir sağladıktan render. Birazdan sayfasını tıklayın ve kaynağını görüntülemek eğer

olursa olsun, gizli alan gibi pek vermektedir:

<input data-val="false" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="0" /> 

Modeli

public partial class AgentTransmission 
{ 
    public int ID { get; set; } 
    . 
    . 
    . 
} 

Görünüm

@model MonetModelFromDb.Models.AgentTransmission 

@{ 
    ViewBag.Title = "Create new Agent"; 
} 

@Html.HiddenFor(model => model.CreatedDate, new { data_val = "false" }) 
@Html.HiddenFor(model => model.CreatedOperator, new { data_val = "false" }) 
@Html.HiddenFor(model => model.ReferenceNumber, new { data_val = "false" }) 
@Html.HiddenFor(model => model.Region, new { data_val = "false" }) 
@Html.HiddenFor(model => model.INDDist, new { data_val = "false" }) 
@Html.HiddenFor(model => model.LastChangeDate, new { data_val = "false" }) 
@Html.HiddenFor(model => model.LastChangeOperator, new { data_val = "false" }) 
@Html.HiddenFor(model => model.EditTaxId, new { data_val = "false" }) 
@Html.HiddenFor(model => model.ParentId, new { data_val = "false" }) 
@Html.HiddenFor(model => model.IsSubstat, new { data_val = "false" }) 
@Html.HiddenFor(model => model.ID, new { data_val = "false" }) 

Ben HiddenFor yardımcı çıkarmak sadece render input etiketi yapıştırmak/keserseniz

<input data-val="false" data-val-date="The field CreatedDate must be a date." id="CreatedDate" name="CreatedDate" type="hidden" value="" /> 
<input data-val="false" id="CreatedOperator" name="CreatedOperator" type="hidden" value="" /> 
<input data-val="false" id="Region" name="Region" type="hidden" value="NM-834" /> 
<input data-val="false" id="INDDist" name="INDDist" type="hidden" value="834" /> 
<input data-val="false" data-val-date="The field LastChangeDate must be a date." data-val-required="The LastChangeDate field is required." id="LastChangeDate" name="LastChangeDate" type="hidden" value="4/8/2015 10:43:30 AM" /> 
<input data-val="false" id="LastChangeOperator" name="LastChangeOperator" type="hidden" value="TYPCLS" /> 
<input data-val="false" data-val-required="The EditTaxId field is required." id="EditTaxId" name="EditTaxId" type="hidden" value="False" /> 
<input data-val="false" data-val-number="The field ParentId must be a number." id="ParentId" name="ParentId" type="hidden" value="" /> 
<input data-val="false" data-val-required="The IsSubstat field is required." id="IsSubstat" name="IsSubstat" type="hidden" value="False" /> 
<input data-val="false" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="0" /> 

Kontrolör

[HttpPost] 
    [MonetAuthorize] 
    public ActionResult Create(AgentTransmission agenttransmission, bool andAddAgent = false) 
    { 
    . 
    . 
    . 
     //Determine if this is first POST or not 
     if (agenttransmission.ID > 0) 
     { 
      db.Entry(agenttransmission).State = EntityState.Modified; 
     } 
     else 
     { 
      db.AgentTransmission.Add(agenttransmission); 
     } 
     db.SaveChanges(); 

     //Send back to view if errors pressent 
     if (!String.IsNullOrWhiteSpace(errorMsg)) 
     { 
      return View(agenttransmission); 
     }   
    } 

DÜZENLEME

, ben açabiliyorum HiddenFor Bölüm Rendered Corret PK değerini yakala. Ancak, bu yüzden (mümkünse) bu soru üzerine

<input data-val="false" id="ID" name="ID" type="hidden" value="@Model.ID" /> 
+0

Geçmişte böyle garip bir şeyle karşılaştığımı hatırlıyorum ve yardımcıyı kullanmak yerine doğrudan alan oluşturmaya başladım. Görünümünüze koyarsanız doğru kimliği gösterir mi? –

+0

Evet, ancak daha zarif bir çözüm bulmayı umuyordum ... eğer mümkün olursa. – NealR

+0

Birkaç farklı şeyi denedim, ancak bu durumlarda çalışmaya başararak başarılı olamadım. Her zaman etrafta çalıştı. Umarım bir başkası daha zarif bir çözüme sahip olur. –

cevap

6

Varyasyonları buraya sık sık sorulur daha zarif bir çözüm bulmak için umuyordum biraz hacky olduğunu. Temel olarak ModelState nesnesine döner ve değerleri, görünüm için gerçek modeldeki değerleri geçersiz kılar. Formu gönderdiğinizde, 0, ID özelliğiniz için ModelState nesnesinde ayarlanır. Son eylemde, ID özelliğinin güncelleştirilmesine neden olan öğeyi kaydedersiniz, ancak 0 hala ModelState dur. Görünümü döndürdüğünüzde, 0, ID için tekrar değer olarak yeniden ayarlandığından, tekrar ModelState olanıdır.

en iyisi bir örnekle açıklanabilir bu şekilde çalışır nedeni. "Foo" olarak ayarlanmış bir Name özelliğine sahip mevcut bir varlığı düzenlediğiniz bir formunuz olduğunu varsayalım. Kullanıcı bunu formda "Bar" olarak değiştirir ve formu gönderir.Ancak, zorunlu bir alanı doldurmayı ihmal ettikleri için, bu hata onların güncellemelerinin kaydedilmesini engeller. Bu noktada ne olmalı? Model değerini kullanırsak, Name alanı "Foo" olarak sıfırlanır. Ancak, ModelState kullanılıyorsa, Name alanı, kullanıcının "Bar" modifikasyonunu korur. İkinci durumda, sadece hatayı düzeltir ve tekrar gönderirler. Eskide, daha önce formda yaptıkları tüm değişiklikleri yeniden yapmalılar ki bu çok zayıf bir kullanıcı deneyimi olurdu.

Şimdi, bunu nasıl düzelteceğinizle ilgili olarak. En iyi yol, PRG şablonunu (Post-Yönlendirme-Get) takip etmektir. Gönderim iyi ise ve değişiklikleri başarılı bir şekilde kaydettiyseniz, kullanıcının hemen ek değişiklikler yapmasını isteseniz bile görünümü döndürmeyin. Bunu isterseniz, aynı eylemi tekrar yönlendirin, ancak yönlendirme işlemi ModelState'u temizlemek için yeterlidir, böylece kullanıcı artık güncel veritabanından yeni güncellenen modelle etkileşime girer.

Bu mümkün değilse, ModelState'u temizleyebilirsiniz. Yukarıdaki örnekte ayrıntılı olarak açıklandığı gibi çok gerçek bir kullanıcı hayal kırıklığına neden olabileceğinden, tamamen temizlemenizi tavsiye ederim. Gerçekten bir yönlendirme yapamıyorsanız, yalnızca gerçekten ihtiyacınız olan ModelState'daki değerleri temizlemeyi deneyin.

ModelState.Remove("ID");