My model is set up so the controller can deliver a Json response of data from user input. The 'rgba' property of my model is an array of ints. If a user enters text of say '255, 0, 0, 1' into the TextBoxFor for 'rgba', the text is not mapping into an array (which I thought was supposed to happen automagically). Instead, int[0] is what makes it to the controller.
I've tried all the potential solutions I could find on here, including passing a FormCollection object to controller. I've tried to get the TextBoxFor value using JS/jQuery and manipulate the data, but can't figure out how to pass the manipulated data back to the model (this seems less than ideal, like there should be an easy way to do this in .Net).
Controller:
public class HomeController : Controller
{
public IActionResult NewColor()
{
Rootobject newColor = new Rootobject();
return View(newColor);
}
[HttpPost]
public IActionResult NewColor(Rootobject color)
{
var json = JsonConvert.SerializeObject(color);
return Json(json);
}
}
Model:
public class Rootobject
{
public Color[] colors { get; set; }
}
public class Color
{
public string color { get; set; }
public string category { get; set; }
public string type { get; set; }
public Code code { get; set; }
}
public class Code
{
public int[] rgba { get; set; }
public string hex { get; set; }
}
View:
@model WebAppPlayground.Models.Rootobject
@{
ViewData["Title"] = "New Color";
}
<style>
input:focus {
border-radius: 5px;
}
input {
padding: 2px;
border-radius: 5px;
border-style: ridge;
}
</style>
<h2>New Color</h2>
<h4>Color</h4>
<hr />
<center>
@using (Html.BeginForm("NewColor", "Home", FormMethod.Post, new { id = "form" }))
{
<table style="border-collapse:separate; border-spacing: 5px 5px">
<tbody>
<tr class="form-group" for="Color">
<td>Color</td>
<td>@Html.TextBoxFor(m => m.colors[0].color)</td>
</tr>
<tr class="form-group">
<td class="">Category</td>
<td>@Html.TextBoxFor(m => m.colors[0].category)</td>
</tr>
<tr class="form-group">
<td class="">Type</td>
<td>@Html.TextBoxFor(m => m.colors[0].type)</td>
</tr>
<tr class="form-group">
<td class="">rgba</td>
<td>@Html.TextBoxFor(m => m.colors[0].code.rgba, new { id = "rgba"})</td>
</tr>
<tr class="form-group">
<td class="">Hex</td>
<td>@Html.TextBoxFor(m => m.colors[0].code.hex)</td>
</tr>
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
}
<div>
<a asp-action="Index">Back to List</a>
</div>
</center>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
I would like my Controller to receive an array of Int's via rgba TextBoxFor where user enters text eg 255, 0, 0, 1.
I think there is something (obvious) I am overlooking or not understanding.
****Updated controller post method to remove added 'rgba_str' prop per @i_ll_be_back 's answer and deliver desired Json data:
[HttpPost]
public IActionResult NewColor(Rootobject color)
{
var json = JsonConvert.SerializeObject(color);
JObject jsonObject = JObject.Parse(json);
JObject code = (JObject)jsonObject["colors"][0]["code"];
code.Property("rgba_str").Remove();
return Json(jsonObject);
}
ModelBinderclass for this. Without that, MVC will not understand that a certain formatted string (that it has no knowledge of) needs to be (1) split at commas and (2) each part converted toint. You can find lots of ModelBinder tutorials on e.g. YouTube.ModelState.IsValidandHtml.ValidationMessageFor/Html.ValidationSummary.