Friday, May 22, 2015

Telerik ASP.Net MVC model binding

Spend a full day working on model binding using KendoUI ASP.NET MVC grid component, the problem is as following:

there are two view models defined:

public class AccountViewModel
    {
        [Key]
        public int AccountId { get; set; }

        [StringLength(10)]
        [DisplayName("Account")]
        public string AccountCode { get; set; }

        [StringLength(100)]
        [DisplayName("Account name")]
        public string AccountName { get; set; }

        [Display(Name = "Account type")]
        public int? AccountTypeId { get; set; }

        [UIHint("ClientAccountType")]
        [Display(Name = "Account Type")]
        public AccountTypeViewModel AccountType { get; set; }

        public bool Inactive { get; set; }
    }

public class JournalEntryTypeAccountViewModel
    {
        [Key]
        public int JournalEntryTypeAccountId { get; set; }

        public int JournalEntryTypeId { get; set; }

        [Required]        public int? AccountId { get; set; }

        [DisplayName("Account")]
        public string AccountCode { get; set; }

        [DisplayName("Account name")]
        public string AccountName { get; set; }

        [Display(Name = "Account type")]
        public string AccountTypeName { get; set; }

        public bool Inactive { get; set; }

        [UIHint("ClientAccount")]
        public AccountViewModel Account { get; set; }
    }

and now I define the grid as following:
@(Html.Kendo().Grid()
    .Name("gridJournalEntryTypeAccount")
    .Columns(columns =>
    {
        columns.Bound(c => c.Account).ClientTemplate("#=Account.AccountCode#").Width(80);
        columns.Bound(c => c.AccountName).Width(240);
        columns.Bound(c => c.AccountTypeName).Width(100);
        columns.Bound(c => c.Inactive).Width(60).ClientTemplate(
            "                "# if (Inactive) { #" +
                    "checked='checked'" +
                "# } #" +
            "/>");
        columns.Command(command =>
        {
            command.Edit();
            command.Destroy();
        }).Width(80);
    })
    .ToolBar(toolBar =>
        {
            toolBar.Create();
        })
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .DataSource(dataSource => dataSource
        .Ajax()
        .ServerOperation(false)
        .PageSize(20)
        .Model(model =>
        {
            model.Id(p => p.JournalEntryTypeAccountId);
            model.Field(p => p.Account).DefaultValue(ViewData["defaultAccount"] as AccountViewModel);
        })
        .Read(read => read.Action("GetJournalEntryTypeAccounts", "JournalEntryType", new { journalEntryTypeId = journalEntryTypeId }))
        .Create(create => create.Action("AddAccount", "JournalEntryType", new { journalEntryTypeId         .Update(update => update.Action("UpdateAccount", "JournalEntryType"))
        .Destroy(destroy => destroy.Action("RemoveAccount", "JournalEntryType", new { journalEntryTypeId = "#=JournalEntryTypeId#", accountId = "#=AccountId#" }))
    )
    .Pageable()
    .Sortable())
 

in the controller action, I have the following:
        [AcceptVerbs(HttpVerbs.Post)]
        public JsonResult AddAccount([DataSourceRequest] DataSourceRequest request,
            JournalEntryTypeAccountViewModel account)
        {
            ......

            return Json(new[] { account }.ToDataSourceResult(request, ModelState));
        }
 
somehow, the account object always getting null on it's account sub-object, spending a whole day to find the problem ...... then eventually works after rename variable name from account to jeAcct

What a Joke!

No comments: