Entity Model for Country (All models are in a separate project)
[ScaffoldColumn(false)]public int CountryId { get; set; }public string ShortName { get; set; }public string LongName { get; set; }public string IsoCode2 { get; set; }public string IsoCode3 { get; set; }public string IsoCodeHash { get; set; }public string CallingCodeOne { get; set; }public string CallingCodeTwo { get; set; }public string CurrencyName { get; set; }public string CurrencySymbol { get; set; }public List<State> States { get; set; }Entity Model for State
[ScaffoldColumn(false)]public int StateId { get; set; }public string Name { get; set; }public bool IsCapital { get; set; }[ScaffoldColumn(false)]public int CountryId { get; set; }public Country Country { get; set; }
States Controller deriving from ODataController (It's a separate project)
private DataAccess.Helper.DatabaseContext _dbContext;public StatesController(){ DataAccess.MyApp.StartUp.Initialize(); const string dataSource = "My-PC\\SQLEXPRESS"; const string initialCatalog = "BS"; var connString = SqlConnection.CreateConnectionString("", dataSource, initialCatalog); _dbContext = new DatabaseContext(connString);}// GET odata/Countries[EnableQuery]public System.Linq.IQueryable<State> GetStates(){ return _dbContext.States;}public IHttpActionResult Put([FromODataUri] int key, State entity){ if (!ModelState.IsValid) return BadRequest(ModelState); if (key != entity.StateId) return BadRequest(); _dbContext.States.Attach(entity); _dbContext.Entry(entity).State = EntityState.Modified; try { _dbContext.SaveChanges(); } catch (Exception) { if (!EntityExists(key)) { return NotFound(); } else { throw; } } return Updated(entity);}private bool EntityExists(int key){ return _dbContext.States.Count(e => e.StateId == key) > 0;}public IHttpActionResult Post(State entity){ if (!ModelState.IsValid) return BadRequest(ModelState); _dbContext.States.Add(entity); _dbContext.SaveChanges(); return Created(entity);}
View (It's in a separate project)
@(Html.Kendo().Grid<SC.BS.EntityModel.State>() .Name("EntityStates") .Columns(col => { col.Bound(e => e.StateId); col.Bound(e => e.Name).Title("State").Width("200"); col.Bound(e => e.IsCapital).Title("Capital").Filterable(false).Width(100).ClientTemplate("#= IsCapital ? 'Yes':'No' #").HtmlAttributes(new {style="align=center"}); col.Bound(e => e.CountryId); col.Bound(e => e.Country).Title("Country").ClientTemplate("#: Country.ShortName #").EditorTemplateName("CountriesLookUp").Filterable(false); col.Command(cmd => { cmd.Edit(); cmd.Destroy(); }).Width(170); }) .Scrollable() .ToolBar(tb => tb.Create().Text("New State")) .DataSource(ds => ds .Custom() .Schema(sch => { sch.Model(m => { m.Id("StateId"); m.Field(e => e.StateId).Editable(false); m.Field(e => e.CountryId).DefaultValue(1); //m.Field(e => e.Country).DefaultValue(new SC.BS.EntityModel.Country()); //m.Field("CreatedOn", typeof(DateTime)); }); }) .Type("odata-v4") .Transport(tr => { tr.Read(r => r.Url("http://localhost:28016/oData/States").Data("function() {return {'$expand' : 'Country'} }")); tr.Create(c => c.Url("http://localhost:28016/oData/States")); tr.Update(new { url = new Kendo.Mvc.ClientHandlerDescriptor { HandlerName = @"function(data) { return 'http://localhost:28016/oData/States(' + data.StateId + ')'; }" } }); tr.Destroy(new { url = new Kendo.Mvc.ClientHandlerDescriptor { HandlerName = @"function(data) { return 'http://localhost:28016/oData/States(' + data.StateId + ')'; }" } }); }) .PageSize(20) .ServerPaging(true) .ServerSorting(true) .ServerFiltering(true) ) .Pageable() .Sortable() .Filterable(ftb => ftb.Mode(GridFilterMode.Row)) .Editable(e => e.Mode(GridEditMode.InLine)))
CountriesLookUp EditorTemplate
@model SC.BS.EntityModel.Country@(Html.Kendo().DropDownList().Name("Countries").DataSource(ds => ds .Custom() .Schema(sch => { sch.Model(m => { m.Id("CountryId"); }); }) .Type("odata-v4") .Transport(tr => { tr.Read(r => r.Url("http://localhost:28016/oData/Countries")); })).DataValueField("Country").DataTextField("ShortName"))
Displaying data works fine, but I'am having trouble updating the State.
- When I click edit, DropDown preselect top/first country instead of selecting the country that state belongs to.
- After changing values, update doesn't work, my ​Web​AP complaints in Put method that the ModelState is invalid and errors out:
-
message=entity : The property'Countries'does not exist on type'SC.BS.EntityModel.State'. Make sure to only use property names that are defined by the type. -
This is the JSON that is sent on update command.{"StateId":"1","Name":"Delhi","IsCapital":true,"CountryId":"2","Country":{"CountryId":2,"ShortName":"United States","LongName":"United States of America","IsoCode2":"US","IsoCode3":"USA","IsoCodeHash":"840","CallingCodeOne":"1","CallingCodeTwo":"","CurrencyName":"USD","CurrencySymbol":"$"},"Countries":"United States"}