0

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);
        }
3
  • 1
    You will need a custom ModelBinder class 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 to int. You can find lots of ModelBinder tutorials on e.g. YouTube. Commented Oct 3, 2019 at 13:31
  • Thank you. I was able to use @i_ll_be_back 's model to get desired my desired result. I will research this later today and update for which solution is best. Commented Oct 3, 2019 at 17:16
  • That can also work, but only a ModelBinder has the advantage that it can integrate seamlessly with ModelState.IsValid and Html.ValidationMessageFor / Html.ValidationSummary. Commented Oct 4, 2019 at 0:26

1 Answer 1

1

Try the following reshaping the Code class in the following:

public class Code
{
    public int[] rgba { get; set; }
    public string rgba_str
    {
        get
        {
            var res = "";
            for(int i = 0; i < rgba.Length; i++) {
                res += rgba[i] + (i != rgba.Length - 1 ? "," : "");
            }
            return res;
        }
        set
        {
            var strArray = value.Split(',');
            rgba = new int[strArray.Length];
            for(int i = 0; i < strArray.Length; i++) {
                rgba[i] = int.Parse(strArray[i]);
            }
        }
    }
    public string hex { get; set; }
}

Now bind the TextBoxFor with the rgba_str field

Sign up to request clarification or add additional context in comments.

1 Comment

I was able to get the proper Json delivered by using the above model, then updating my post controller to remove the added string rgba_str prop... see updated OP for new controller code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.