So I have a controller like this:
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; }
}
And a view like this:
<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>
}
When I post the form my controller throws the exception because LanguageStrings is null. The strange part I mentioned in the title is that if I add one more record to the list everything works. Like this:
<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>
}
It also works when I remove the "Deleted" list. Like this:
<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>
}
This has something to do with the naming I am using. I have already solved the problem with renaming LanguageStrings to something else. But I would like to understand what is happening here because probably I could learn something from it how MVC maps request body and will be able to avoid similar time consuming problems. Please help me and explain the cause of this.
Type = model. Type. Trim(); whenever null values coming from the database occurs.
cshtml as the view not found in Index but in the web. config file. The error statusCode="404" means that the file is not found and it means the controller name or controller action method name is the issue.
A PostBack in ASP.NET Web Forms is an HTTP Post. IsPostBack is a standard pattern in Web Forms to determine if the page request is a GET or a POST. This pattern does not apply to MVC. In MVC, the initialization code goes in an [HttpGet] action and the form processing code goes in an [HttpPost] action.
You found a bug in the PrefixContainer of MVC 4 which has already been fixed in MVC 5.
Here is the fixed version with comments about the bug:
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With