When I try and create a new 'Flow' class the nested classes ('Action') always come back as null in the controller
So I have classes within classes like so:
public class Flow
{
private Action actionField
private string nameField
private bool enabledField
...
}
public class Action
{
private ActionSchedule actionScheduleField
private ActionParameter actionParameterField
private nameField
}
public class ActionSchedule
...
And a single create view for a 'Flow'
@model ProjectZeus.Models.Flow
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.TextBoxFor(model => model.name, new { @placeholder = "Flow name" })
@Html.ValidationMessageFor(model => model.name)
@Html.LabelFor(model => model.enabled)
@Html.EditorFor(model => model.enabled)
@Html.ValidationMessageFor(model => model.enabled)
@Html.Partial("FlowAction")
...
and then partial views for each of the subclasses
@model ProjectZeus.Models.FlowAction
@Html.TextBoxFor(model => model.name, new { @placeholder = "Action name" })
...
I've tried creating instances of the classes and calling the view - error,
I've tried creating instances of the classes in the views themselves - error,
I've tried not using PartialViews:
@Html.TextBoxFor(model => model.action.name, new { @placeholder = "Action name" })
I've googled and googled and googleedddd but with no luck, help please!?
Edit:
Implementing a customer model binder seems like overkill. This page describes the same problem but the solution code won't compile for me ‘The name ‘helper’ does not exist in the current context’? - http://danielhalldev.wordpress.com/2013/08/23/partial-views-and-nested-mvc-model-binding/
Edit2:
I changed the model defintions for brevity - the model is actually auto generated from an xsd:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class D53ESBFlow
{
private D53ESBFlowAction actionField;
[Required]
private string nameField;
...
private bool enabledField;
/// <remarks/>
public D53ESBFlowAction action
{
get
{
return this.actionField;
}
set
{
this.actionField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
Edit 3 (bump):
It looks like the 'binder'is creating a property and not a class object?
MVC doesn't use data bindings like old web api. You have to use model bindings in a MVC or MVVM approach.
Model binding allows you map request parameters to actions. This means action methods will have one or more parameters and those parameters will receive their values from the model binding framework.
Model binding is a simplistic way to correlate C# code with an HTTP request. The model binding applies to transforming the HTTP request data in the query's form string and form collection of the action method parameters. We can consider these parameters to be primitive type or complex type.
Did you forget the { get; set; } accessors on the property names?
I had a similar issue with MVC 5, .NET 4.5, Visual Studio 2013.
Here's what worked for me: Add a constructor so the contained class gets instantiated, make them properties (not variables) like AntoineLev said, and add the class to the Binding:
public class Flow
{
public Action actionField {get; set; }
public class Flow()
{
actionField = new Action(); // otherwise it shows up as null
}
}
In your controller, Add the the whole class in the binding:
public ActionResult Create([Bind(Include="action,name,enabled")] Flow flow)
{
...
}
Your Mileage may vary.
}
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