This is a migrated thread and some comments may be shown as answers.

Foreign Key DropDown in Grid and WebAPI

2 Answers 158 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Dinesh
Top achievements
Rank 1
Dinesh asked on 13 Aug 2015, 09:39 PM

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.

  1. When I click edit, DropDown preselect top/first country instead of selecting the country that state belongs to.
  2. After changing values, update doesn't work, my ​Web​AP complaints in Put method that the ModelState is invalid and errors out:
  3. 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.
  4. 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"}

2 Answers, 1 is accepted

Sort by
0
Dinesh
Top achievements
Rank 1
answered on 15 Aug 2015, 05:40 AM
Anyone?
0
Boyan Dimitrov
Telerik team
answered on 18 Aug 2015, 06:45 AM

Hello Dinesh,

 

The Name of the DropDownList in the EditorTemplate should match the model property/field you are updating with this DropDownList widget. 

 

As far as I understand you are trying to update the Country property of the Model, but the Name for the DropDownList is set to "Countries". My suggestion would be to use the DropDownListFor as explained in Editor Templates article

 

As a side note the current implementation uses editor templates approach. If you want to use the ForeignKey approach please refer to the Grid / ForeignKey column demo. 

 

Regards,
Boyan Dimitrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Grid
Asked by
Dinesh
Top achievements
Rank 1
Answers by
Dinesh
Top achievements
Rank 1
Boyan Dimitrov
Telerik team
Share this question
or