Foreign Key DropDown in Grid and WebAPI

3 posts, 0 answers
  1. Dinesh
    Dinesh avatar
    2 posts
    Member since:
    Aug 2015

    Posted 13 Aug 2015 Link to this post

    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. Dinesh
    Dinesh avatar
    2 posts
    Member since:
    Aug 2015

    Posted 15 Aug 2015 Link to this post

    Anyone?
  3. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    2048 posts

    Posted 18 Aug 2015 Link to this post

    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
Back to Top