2013-11-21 17 views
6

Bu yüzden bir böyle denetleyicisi vardır:ASP.NET MVC Mesaj liste çok garip koşullar altında boş olur

public class TestController : Controller 
    { 
     // 
     // GET: /Test/ 

     public ActionResult Index() 
     { 
      return View("Test"); 
     } 

     public ActionResult Post(IList<Test> LanguageStrings, IList<Test> LanguageStringsGroup, IList<string> Deleted, IList<string> DeletedGroup) 
     { 
      if (LanguageStrings == null) 
      { 
       throw new ApplicationException("NULL"); 
      } 


      return View("Test"); 
     } 

    } 

    public class Test 
    { 
     public string Val { get; set; } 
     public string Another { get; set; } 
    } 

Ve böyle bir manzara:

<h2>Test</h2> 

@using (Html.BeginForm("Post", "Test")) 
{ 
    @Html.Hidden("LanguageStrings[0].Val", "test1") 
    @Html.Hidden("LanguageStrings[0].Another") 
    @Html.Hidden("LanguageStrings[1].Val", "test2") 
    @Html.Hidden("LanguageStrings[1].Another") 

    @Html.Hidden("LanguageStringsGroup[0].Val", "test4") 

    @Html.Hidden("Deleted[0]") 
    @Html.Hidden("Deleted[1]") 
    @Html.Hidden("Deleted[2]") 

    @Html.Hidden("DeletedGroup[0]") 

    <button>Post</button> 
} 

Ben formu benim denetleyicisi zaman sonrası istisna atar, çünkü LanguageStrings boştur. Başlıkta bahsettiğim garip kısım, listeye bir tane daha kayıt eklersek her şeyin işe yarayacağıdır. Bunun gibi : Ben "Silinmiş" listesi kaldırdığınızda

<h2>Test</h2> 

@using (Html.BeginForm("Post", "Test")) 
{ 
    @Html.Hidden("LanguageStrings[0].Val", "test1") 
    @Html.Hidden("LanguageStrings[0].Another") 
    @Html.Hidden("LanguageStrings[1].Val", "test2") 
    @Html.Hidden("LanguageStrings[1].Another") 
    @Html.Hidden("LanguageStrings[2].Val", "test3") 
    @Html.Hidden("LanguageStrings[2].Another") 

    @Html.Hidden("LanguageStringsGroup[0].Val", "test4") 

    @Html.Hidden("Deleted[0]") 
    @Html.Hidden("Deleted[1]") 
    @Html.Hidden("Deleted[2]") 

    @Html.Hidden("DeletedGroup[0]") 

    <button>Post</button> 
} 

Ayrıca çalışır. Bunun gibi :

<h2>Test</h2> 

@using (Html.BeginForm("Post", "Test")) 
{ 
    @Html.Hidden("LanguageStrings[0].Val", "test1") 
    @Html.Hidden("LanguageStrings[0].Another") 
    @Html.Hidden("LanguageStrings[1].Val", "test2") 
    @Html.Hidden("LanguageStrings[1].Another") 

    @Html.Hidden("LanguageStringsGroup[0].Val", "test4") 

    @Html.Hidden("DeletedGroup[0]") 

    <button>Post</button> 
} 

Bu kullanıyorum adlandırma ile ilgili bir şey vardır. DilStrings'i başka bir şeye yeniden adlandırma ile sorunu zaten çözdüm. Ama burada neler olduğunu anlamak isterim çünkü muhtemelen MVC haritalarının vücut talep etmesini ve benzer zaman alıcı problemlerden sakınmayı nasıl başarabileceğimi öğrenebilirim. Lütfen bana yardım et ve bunun nedenini açıkla.

cevap

5

Zaten MVC giderilmiştir MVC 4 PrefixContainer bir hata buldum 5. İşte

ile sabit versiyonudur Bu kod hakkında yorumlar:

internal bool ContainsPrefix(string prefix) 
{ 
    if (prefix == null) 
    { 
     throw new ArgumentNullException("prefix"); 
    } 

    if (prefix.Length == 0) 
    { 
     return _sortedValues.Length > 0; // only match empty string when we have some value 
    } 

    PrefixComparer prefixComparer = new PrefixComparer(prefix); 
    bool containsPrefix = Array.BinarySearch(_sortedValues, prefix, prefixComparer) > -1; 
    if (!containsPrefix) 
    { 
     // If there's something in the search boundary that starts with the same name 
     // as the collection prefix that we're trying to find, the binary search would actually fail. 
     // For example, let's say we have foo.a, foo.bE and foo.b[0]. Calling Array.BinarySearch 
     // will fail to find foo.b because it will land on foo.bE, then look at foo.a and finally 
     // failing to find the prefix which is actually present in the container (foo.b[0]). 
     // Here we're doing another pass looking specifically for collection prefix. 
     containsPrefix = Array.BinarySearch(_sortedValues, prefix + "[", prefixComparer) > -1; 
    } 
    return containsPrefix; 
} 
+0

Bu kod nereye gitmeli? – raklos

+0

MVC5 bu koda sahiptir, bu yüzden MVC5'e geçin. İşte PrefixContainer en son kaynak kodu https://aspnetwebstack.codeplex.com/SourceControl/latest#src/Common/PrefixContainer.cs – LostInComputer

0

Denetleyiciye geri göndermek için @ Html.HiddenFor() ile daha fazla başarı elde ettim. Kod şöyle görünecektir:

@for (int i = 0; i < @Model.LanguageStrings.Count; i++) 
{ 
    @Html.HiddenFor(model => model.LanguageStrings[i].Val, string.Format("test{0}", i)) 
    @Html.HiddenFor(model => model.LanguageStrings[i].Another) 
} 

En HTML yardımcı yöntemler bir modellere veri bağlama için kullanılmak üzere tasarlanmıştır yardımcı "için" var. İşte yöntemler de "İçin" açıklıyor sitede başka post: What is the difference between Html.Hidden and Html.HiddenFor