2

Theres links already on how to use multiple models for a view with different ways to do it, however, I tried those and could not get them to work, what am I doing wrong?

I simply want two form inputs in 1 view, and one model, but one of the form inputs uses a list<'model'> and the other uses 'model', here's what I mean:

UPDATE: copy/paste this code, if you select and submit any check box items you will get an error at @Model.input.passWord and I have no idea why, checkbox items wont show either, need help.

View (Index.cshtml):

@using stupidassTests.Models
@model  MyViewModel


@{
ViewBag.Title = "Index";


}

<h2>Password Input</h2>

<div>
<p>Enter Password</p>
@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
    @Html.TextBox("password")

    <button type="submit" value="Search"></button>
}

<p>@Model.input.passWord</p> <!--passWord is underlined with red because it conflicts with the List'model'-->

</div>

<h2>Checkbox</h2>

<div>

@using (Html.BeginForm())
{
    for (var i = 0; i < Model.inputCollection.Count; i++)
    {
        <p>
            @Html.HiddenFor(n => n.inputCollection[i].Id)
            @Html.DisplayFor(n => n.inputCollection[i].Name)
            @Html.HiddenFor(n => n.inputCollection[i].Name)
            @Html.CheckBoxFor(n => n.inputCollection[i].Checked)
        </p>

    }

    <input id="Submit1" type="submit" value="submit" />


    if (ViewBag.Values != null)
    {
        foreach (var item in ViewBag.Values)
        {
            <p>@item</p>
        }
    }



}

So as you can see, copy/paste my code and try to run it, 'password' form input is being shoved out by 'checkbox' input, it seems the two '@model' are conflicting under one model class, how do I fix this?

Controller (HomeController.cs):

public ActionResult Index() {

        return View();
    }



    [HttpGet, ActionName("Index")]
    public ActionResult PasswordInput(string password)
    {
        FormInputs pss = new FormInputs();

        pss.passWord = password;

        MyViewModel mvm = new MyViewModel() { input = pss, isList = false };

return this.View("Index", mvm);

    }





    [HttpGet]
    public ActionResult CheckBoxGet()
    {


        var list = new List<FormInputs>
        {
             new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
        new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
         new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
         new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
         new FormInputs { Id = 5, Name = "Bailley", Checked = false },
         new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
         new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
         new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
         new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
         new FormInputs { Id = 10, Name = "Dislaren", Checked = false },

 };
        MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);

    }


    [HttpPost]
    public ActionResult CheckBoxPost(List<FormInputs> list)
    {


        var selected = list.Where(x => x.Checked).Select(x => x.Name);

        ViewBag.Values = selected;

        MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };

        return this.View("Index", mvm);
    }

Model (FormInputs.cs):

public class MyViewModel
{
    public FormInputs input;
    public List<FormInputs> inputCollection;
    public bool isList;
}
public class FormInputs
{
    public string passWord = "";


    public int Id { get; set; }
    public string Name { get; set; }
    public bool Checked { get; set; }

    public List<string> checkBox = new List<string>();


}

So just as a summary, because I'm a beginner at MVC, how do I re-work this code (btw copy/paste it) so that both form inputs can co-exist in 1 view?

  • 3
    Just create a view model containing 2 properties - `FormInputs Property1` and `List Property 2` –  May 23 '16 at 04:25
  • 2
    From my knowledge, you can't have multiple models in a single view in MVC. You should make use of dynamic models or ViewModel pattern to achieve this. http://stackoverflow.com/questions/5550627/two-models-in-one-view-in-asp-mvc-3 could help you. – geothachankary May 23 '16 at 04:26
  • But what is the point of this? You can only post back one form at a time –  May 23 '16 at 04:26
  • @StephenMuecke hey there, let's join a chatroom this is new to me –  May 23 '16 at 05:57

2 Answers2

1

You can use viewmodel.

Use ViewModel

For view model you have to create a class and in this class you will define all models as properties of this class.Here are two classes.

public class EmployeeDetails
{
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

}

public class Employee
{
    public int Id { get; set; }
}

Here is viewmodel

public class ViewModel
{
    public Employee emp { get; set; }
    public EmployeeDetails empdet{ get; set; }
}

Now in Controller you will do like this

public ActionResult About()
{
        ViewModel vm = new ViewModel();
        vm.emp = new Employee();
        vm.empdet = new EmployeeDetails();
        return View(vm);
}

And in view you will receive it like this

@model ViewModel
Mairaj Ahmad
  • 14,434
  • 2
  • 26
  • 40
1

This might be a good example to use the Composite Pattern. You can have a ViewModel with two properties:

public class MyViewModel{
    public FormInputs input;
    public List<FormInputs> inputCollection;
    public bool isList;
}

And arrange the data accordingly:

public ActionResult PasswordInput(string password)
{
    FormInputs pss = new FormInputs();

    pss.passWord = password;

    MyViewModel mvm = new MyViewModel(){input = pss, isList = false}
    return this.View("Index", mvm); 
}

AND

public ActionResult CheckBoxGet()
{
    var list = new List<FormInputs>
    {
         new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
    new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
     new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
     new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
     new FormInputs { Id = 5, Name = "Bailley", Checked = false },
     new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
     new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
     new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
     new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
     new FormInputs { Id = 10, Name = "Dislaren", Checked = false },

    };
    MyViewModel mvm = new MyViewModel(){inputCollection = list , isList = true}
    return this.View("Index", mvm); 

}

AND in view, use this:

@model MyViewModel

Check the isList property before using the input/inputCollection

SamGhatak
  • 1,487
  • 1
  • 16
  • 27
  • getting ambiguous exceptions, but in the code it's showing 0 errors, help! –  May 23 '16 at 07:40
  • Where are you getting the exceptions? – SamGhatak May 23 '16 at 07:48
  • The current request for action 'Index' on controller type 'HomeController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult PasswordInput(System.String) on type stupidassTests.Controllers.HomeController System.Web.Mvc.ActionResult CheckBoxGet() on type stupidassTests.Controllers.HomeController –  May 23 '16 at 07:54
  • Ok, this is not related to your actual problem. To get rid of this, we need to understand why you are using same action name for all the actions? – SamGhatak May 23 '16 at 07:57
  • I removed the same names from checkbox() and the code worked, now I got another exception, when run app, checkbox names don't appear next to the check boxes and when I select checkbox items and 'submit' I get an exception at @Model.passWord that object reference not set to instance of an object –  May 23 '16 at 08:06
  • It suggests that the model is null, please check whether the correct action is getting called and why you are getting it null...If you use `MyViewModel` as suggested in the answer, your property will be `Model.input.passWord`, did you make all the changes? – SamGhatak May 23 '16 at 08:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/112653/discussion-between-fluffywuffy-and-samghatak). –  May 23 '16 at 08:17
  • yea I did make the password change, but I'm not sure what to change in actionresult checkboxpost() –  May 23 '16 at 08:26
  • First check whether you are getting any value in the parameter of the checkboxpost action... – SamGhatak May 23 '16 at 08:29