MVC 3 DevExpress - Model Returned to Controller is Empty

半腔热情 提交于 2019-12-08 00:40:58

问题


The problem is really simple, but I just can't seem to solve it. I am using Razor engine with DevExpress combo box.

I have this code:

MODEL:

public class TestModel
{
    public string Name { get; set; }
    public List<Role> Roles { get; set; }
}

public class Role
{
    public int RoleId { get; set; }
    public string RoleName { get; set; }
}

CONTROLLER

    public ActionResult OpenTest()
    {
        TestModel tm = new TestModel( );
        tm.Roles = new List<Role>( );

        tm.Roles.Add( new Role( ) { RoleId = 1, RoleName = "Role 1" } );
        tm.Roles.Add( new Role( ) { RoleId = 2, RoleName = "Role 2" } );
        tm.Roles.Add( new Role( ) { RoleId = 3, RoleName = "Role 3" } );

        return View( tm );
    }

Here I can successfully open the view, and data is displayed fine:

VIEW

@model TestDx.Models.TestModel
@{
    ViewBag.Title = "OpenTest";
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using ( Html.BeginForm( ) )
{
                        @Html.DevExpress( ).ComboBox(
                    settings =>
                    {
                        settings.Name = "TestDx.Models.TestModel.Roles";
                        settings.Width = 120;
                        settings.SelectedIndex = 0;
                        settings.Properties.DropDownWidth = 300;
                        settings.Properties.DropDownStyle = DevExpress.Web.ASPxEditors.DropDownStyle.DropDownList;
                        settings.Properties.EnableCallbackMode = false;
                        settings.Properties.CallbackPageSize = 30;
                        settings.Properties.IncrementalFilteringMode = DevExpress.Web.ASPxEditors.IncrementalFilteringMode.StartsWith;
                        settings.Properties.TextFormatString = "{0}";
                        settings.Properties.ValueField = "RoleID";
                        settings.Properties.ValueType = typeof( int );

                        settings.Properties.Columns.Add( "RoleID", "RoleID", 10 );
                        settings.Properties.Columns.Add( "RoleName", "RoleName", 100 );

                    } ).BindList( Model.Roles ).GetHtml( )
        <br />
            @Html.DevExpress().Button(
                    settings =>
                    {
                        settings.Name = "btnSave";
                        settings.ClientEnabled = true;
                        settings.ControlStyle.CssClass = "button";
                        settings.ClientVisible = true;

                        settings.Text = "save";
                        settings.UseSubmitBehavior = true;
                        settings.ControlStyle.Font.Bold = true;
                    }).GetHtml()
}

Now all this is very simple, and I am not doing anything with it, just dispaying it. But when I click Save button, I get back to the controller, to this method:

[HttpPost]
        public ActionResult OpenTest( [ModelBinder( typeof( DevExpressEditorsBinder ) )]TestModel model )
        {
            if ( ModelState.IsValid )
            {
               //
            }

            return View( model );
        }

...and Model here is empty, Roles property is 0. I cannot understand why is that? Event the combo box name is the same as the property it is binding to, and I am sure using a recommended DevExpress binder.

Thanks.


回答1:


The name of your ComboBox is listing the type definition. Because you are passing in TestModel as the type, the name of your ComboBox should be the property where the role Id should be saved. So the binder is attempting to fill model.TestDx.Models.TestModel.Roles but can't find that field, and so nothing is getting filled. If you look at the formCollection objects you should see your ComboBox with the value.

A better solution would be to have RoleID specified in TestModel, and name the ComboBox simply RoleID. In that case RoleID should fill automatically on your save. Alternatively, you could specify the Bind field in the view, such as:

 @Html.DevExpress( ).ComboBox(
                    settings =>
                    {
                        settings.Name = "TestDx.Models.TestModel.Roles";
                        settings.Width = 120;
                        settings.SelectedIndex = 0;
                        settings.Properties.DropDownWidth = 300;
                        settings.Properties.DropDownStyle = DevExpress.Web.ASPxEditors.DropDownStyle.DropDownList;
                        settings.Properties.EnableCallbackMode = false;
                        settings.Properties.CallbackPageSize = 30;
                        settings.Properties.IncrementalFilteringMode = DevExpress.Web.ASPxEditors.IncrementalFilteringMode.StartsWith;
                        settings.Properties.TextFormatString = "{0}";
                        settings.Properties.ValueField = "RoleID";
                        settings.Properties.ValueType = typeof( int );

                        settings.Properties.Columns.Add( "RoleID", "RoleID", 10 );
                        settings.Properties.Columns.Add( "RoleName", "RoleName", 100 );

                    } ).BindList( Model.Roles )
                       .Bind(model.RoleID).GetHtml( )

This may work for your binding.




回答2:


The model is not been bound. Your RoleID name attribute must be different than Roles[listIndex].RoleID. To bind lists into your Model, the input name should be ListPropName[listIndex].PropNameInsideList



来源:https://stackoverflow.com/questions/11319969/mvc-3-devexpress-model-returned-to-controller-is-empty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!