Datasource read not being called on initial page load

7 posts, 1 answers
  1. Paul Grothe
    Paul Grothe avatar
    26 posts
    Member since:
    Apr 2010

    Posted 27 Aug 2015 Link to this post

    I have a grid in a partial view and it's data source fails to call the read method on the initial page load.  It does get called when I submit the ajax form, but the problem is that I want some default data to appear in the grid when the page initially loads.

    Also, if I take out the model as a parameter on the read method, then the read method will in fact get called during the initial page load, but the problem with that is then I won't be able to feed it any parameters to filter the data from the ajax form.

     I tried to call the read method from javascript in document.ready() to try and force it to call the read method, but that didn't work.  Is there a way I can make the read method get called in the initial page load while also feeding it the model as a parameter?

     

    Here is the partial view called _ProjectResults

    @model MvcTestProject.Models.ProjectSearchModel
     
    @(Html.Kendo().Grid<MvcTestProject.Models.ProjectItem>()
            .Name("projectresultsgrid")
            .Columns(columns =>
            {
                columns.Bound(p => p.KeyID).Title("Key ID").Width(130);
                columns.Bound(p => p.StoreNumber).Title("Store").Width(130);
                columns.Bound(p => p.ProjectType).Title("Type").Width(150);
                columns.Bound(p => p.ProjectStatus).Title("Status").Width(130);
                columns.Bound(p => p.InstallStartDate).Title("Start Date").Width(130).Format("{0:MM/dd/yyyy}");
     
            })
            .Pageable()
            .Sortable()
            .Scrollable(scr => scr.Height(550))
            .Filterable()
            .DataSource(dataSource => dataSource
                .Ajax()           
                .PageSize(50)
                .ServerOperation(false)
                .Read(data => data.Action("ReadProjects", "Project", Model))
                 
             )
    )

     

    Here is the parent page

    @model MvcTestProject.Models.ProjectSearchModel
     
    @{
        Layout = "~/Views/Shared/_Layout_Project.cshtml";
        ViewBag.Title = "Index";
    }
     
    <h2>Project Search</h2>
    <div>
        @using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "dvProjectResults" }))
        {
     
            <fieldset style="margin:10px;">
                <legend style="margin:5px;font-weight:bold">
                    Search Criteria
                </legend>
                <table>
                    <tr>
                        <td>@Html.LabelFor(m => Model.ProjectTypeID)</td>
                        <td width="400px;">
                            @(Html.Kendo().DropDownListFor(m => m.ProjectTypeID)
                              .HtmlAttributes(new { style = "width: 250px" })
                              .DataTextField("TypeName")
                              .DataValueField("ProjTypeID")
                              .BindTo(Model.ProjectTypeOptions)
                             .OptionLabel(" ")
                            )
                        </td>
                    </tr>
                    <tr>
                        <td>@Html.LabelFor(m => Model.ProjectStatusID)</td>
                        <td>
                            @(Html.Kendo().DropDownListFor(m => m.ProjectStatusID)
                              .HtmlAttributes(new { style = "width: 250px" })
                                .DataTextField("StatusName")
                                .DataValueField("ProjStatusID")
                                .BindTo(Model.ProjectStatusOptions)
                                .OptionLabel(" ")
                            )
                        </td>
                        <td>@Html.LabelFor(m => Model.StartDate)</td>
                        <td>@Html.EditorFor(m => Model.StartDate)</td>
                    </tr>
     
                    <tr>
                        <td>@Html.LabelFor(m => Model.KeyID)</td>
                        <td>@Html.EditorFor(m => Model.KeyID)</td>
                        <td>@Html.LabelFor(m => Model.EndDate)</td>
                        <td>@Html.EditorFor(m => Model.EndDate)</td>
                    </tr>
                    <tr>
                        <td>@Html.LabelFor(m => Model.StoreNumber)</td>
                        <td>@Html.EditorFor(m => Model.StoreNumber)</td>
                    </tr>
                    <tr>
                        <td colspan="2"><input type="submit" value="Search" /></td>
                    </tr>
                </table>
     
            </fieldset>
     
     
        }
     
        <div id="dvProjectResults" style="margin:10px;">
            @{Html.RenderPartial("_ProjectResults", Model);}    
        </div>
    </div>
     
    <script type="text/javascript">
        $(document).ready(function () { JSReadProjects(); });
        function JSReadProjects() {
            var grid = $("#projectresultsgrid").data("kendoGrid");
            grid.dataSource.read();
        }
     
    </script>

     Here is the http post actionresult that is executed when the ajax form is submitted:

    [HttpPost]
    public ActionResult ProjectSearch(ProjectSearchModel model)
    {
        return PartialView("_ProjectResults", model);
    }

    Here is the read method on the controller:

    public ActionResult ReadProjects([DataSourceRequest] DataSourceRequest request, ProjectSearchModel searchModel)
    {
        var data = datamgr.GetProjects
            (
                searchModel.KeyID,
        searchModel.StoreNumber,
                searchModel.ProjectTypeID,
                searchModel.ProjectStatusID,
                searchModel.StartDate,
            );
     
        var serializer = new JavaScriptSerializer();
        var result = new ContentResult();
        serializer.MaxJsonLength = Int32.MaxValue; // Whatever max length you want here
        result.Content = serializer.Serialize(data.ToDataSourceResult(request));
        result.ContentType = "application/json";
        return result;
    }

     

  2. Paul Grothe
    Paul Grothe avatar
    26 posts
    Member since:
    Apr 2010

    Posted 28 Aug 2015 Link to this post

    I found an alternate way of passing the parameters to make this work.  It seems though that the Read method is a little inconsistent and confusing.  Like I mentioned before, if I pass the model straight as into the Read method, it will not get called during the initial page load, but seems to work just fine during my ajax form submission.

     The following adjustment works both during the initial page load and ajax form submission:

    Instead of passing the model straight into the read method.  I convert it to an anonymous type.  Then the system will split the anonymous object and feed each property member as a parameter to the read method on the controller like so:

    This is the read method on the MVC wrapper in the Razor view

    .Read(data => data.Action("ReadProjects", "Project", new {KeyID=Model.KeyID,
                        StoreNumber=Model.StoreNumber,
                        StartDate=Model.StartDate,
                        ProjectStatusID=Model.ProjectStatusID,
                        ProjectTypeID=Model.ProjectTypeID }))

     

    And this is the read method on the controller

    [HttpPost]
    public ActionResult ReadProjects([DataSourceRequest] DataSourceRequest request, string KeyID, string StoreNumber, DateTime? StartDate, int ProjectTypeID, int ProjectStatusID)

     

    It would be nice if I could just pass in the Model and have it work for both scenarios, but this method works.

  3. Daniel
    Admin
    Daniel avatar
    2224 posts

    Posted 31 Aug 2015 Link to this post

    Hi,

    I am not sure what could be causing the problem. Passing the Model should work the same way. The problem could be caused by an exception thrown during the binding of the model so could you check if a request is made in the network traffic and if yes, what is the response from the server. The response message should indicate what exactly is going wrong.

    Regards,
    Daniel
    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
  4. Paul Grothe
    Paul Grothe avatar
    26 posts
    Member since:
    Apr 2010

    Posted 31 Aug 2015 Link to this post

    Yes it is returning an error during the post that is occuring during the initial page load.  I get a MissingMethod exception and it says that it cannot create an interface.

    After further testing I found that I didn't necessarily need to send an anonymous type, it is the parameters on the read method that are the main issue.

    Attached is a test project that demonstrates the issue.  You will see that there are two read methods (ReadProjects and ReadProjects2) that have different signatures.  The ReadProjects Method only works on an Ajax request so if the grid's datasource is set to that then it will not load any data during the initial page load.  ReadProjects2 works in both scenarios.

     

  5. Answer
    Daniel
    Admin
    Daniel avatar
    2224 posts

    Posted 02 Sep 2015 Link to this post

    Hello again,

    The exception is thrown because of the IQuerable properties in the ProjectSearchModel. In order to pass directly the model you could exclude them from the binding:
    public ActionResult ReadProjects([DataSourceRequest] DataSourceRequest request, [Bind(Exclude = "ProjectTypeOptions,ProjectStatusOptions")]ProjectSearchModel searchModel)
    or change their type to List.

    Regards,
    Daniel
    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
  6. Paul Grothe
    Paul Grothe avatar
    26 posts
    Member since:
    Apr 2010

    Posted 02 Sep 2015 Link to this post

    Okay, thanks for the suggestion.

    I am assuming that the reason that it worked during ajax requests is because the IQueryable properties were null during the ajax post.

  7. Daniel
    Admin
    Daniel avatar
    2224 posts

    Posted 04 Sep 2015 Link to this post

    Hello,

    Indeed, the properties were not set in the post action and were not sent with the request so the model binder didn't try to bind them.

    Regards,
    Daniel
    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