-1

I have seen lots of examples on this, but cannot get any working. I have built this example to prove/disprove passing back of the view model SomeDataViewModel.

I am trying to post back the dropdownlist data. Everything works ok, but the OtherData property on TestViewModel never returns the collect that was passed in.

Have tried adding:

@Html.HiddenFor(m => Model.OtherData)

but again this just produces the following error;

The parameter conversion from type 'System.String' to type 'SomeDataViewModel' failed because no type converter can convert between these types

The Code:

ViewModels

TestViewmodel

public class TestViewModel
{

    public TestViewModel()
    {
        OtherData = new List<SomeDataViewModel>();
    }

    public int Id { get; set; }
    public String Name { get; set; }
    public DateTime DoB { get; set; }
    public int SelectedOtherData { get; set; }
    public List<SomeDataViewModel> OtherData { get; set; }

    public IEnumerable<SelectListItem> TolistData()
    {

        IEnumerable<SelectListItem> ret = OtherData.Select(i => new SelectListItem() { Text = i.Text, Value=i.Value });


        return ret;
    }
}

SomeDataViewmodel

 public class SomeDataViewModel
{
    public string Value { get; set; }
    public string Text { get; set; }
}

View

@model TestViewModel

@{
    ViewBag.Title = "Home Page";
}
@using (Html.BeginForm("Index","Home"))
{
<div class="row">
    <div class="col-md-12">
        <br />
        @Html.EditorFor(m => Model.Id)
        <br />
        @Html.EditorFor(m => Model.Name)
        <br />
        @Html.EditorFor(m => Model.DoB)
        <br/>
        @Html.DropDownListFor(m => Model.SelectedOtherData, Model.TolistData(), new { id = "OtherData" })

        <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p>
    </div>
</div>

<button id="dosomething" formmethod="post">Post</button>

}

Controller

    public ActionResult Index()
    {

        var model = new TestViewModel() {
            Id = 99,
            Name = "Billy",
            DoB = DateTime.Now
        };

        model.OtherData.Add(
            new SomeDataViewModel { Text = "Bob", Value = "1" });
        model.OtherData.Add(
            new SomeDataViewModel { Text = "Sally", Value = "2" });

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(TestViewModel retModel)
    {
        if (ModelState.IsValid)
        {
            if (retModel.OtherData.Count() == 0)
            {
                var dud = true;
            }
        }
        return View(retModel);
    }
gilesrpa
  • 969
  • 1
  • 12
  • 35

2 Answers2

2

You can't render hidden inputs for complex data with @Html.HiddenFor helper.

You should use it only with simple types. Becouse you got array you should write something like this:

@for(int i = 0; i < Model.OtherData.Count(); i++)
{
    @Html.HiddenFor(m => Model.OtherData[i].Text)
    @Html.HiddenFor(m => Model.OtherData[i].Value)
    //... other fields.
    @Html.HiddenFor(m => Model.OtherData[i].OtherProperty)
}

Use for loop instead of foreach becouse you should same your mappings for right binding on form POST.

teo van kot
  • 12,350
  • 10
  • 38
  • 70
  • 1
    A bit pointless to send a whole lot of data across the wire and then send it back again unchanged –  May 26 '17 at 11:39
  • 1
    @StephenMuecke agreed. That's also not good becouse client can change it manually if he want. But I just answer OP question – teo van kot May 26 '17 at 11:41
  • Thank you all for your help. I knew that it could not be difficult. In answer to Stephen's post, all I provided here was a simple example that has no reflection on the code I am writing. The plan is to send over a List of objects that can be added to, removed or changed. This is the reason for the requirement. I would have used Ajax and Json, but this is not a green field application, I am just trying to get something to work within the existing code framework. – gilesrpa May 26 '17 at 12:01
0

Certainly there is a type conversion error. your SelectedOtherData is type of int while selectlistitem value is type of string

kashi_rock
  • 539
  • 1
  • 5
  • 19