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

Datasource read not being called on initial page load

6 Answers 892 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Paul Grothe
Top achievements
Rank 1
Paul Grothe asked on 27 Aug 2015, 03:08 PM

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;
}

 

6 Answers, 1 is accepted

Sort by
0
Paul Grothe
Top achievements
Rank 1
answered on 28 Aug 2015, 02:42 PM

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.

0
Daniel
Telerik team
answered on 31 Aug 2015, 11:56 AM
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
0
Paul Grothe
Top achievements
Rank 1
answered on 31 Aug 2015, 08:50 PM

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.

 

0
Accepted
Daniel
Telerik team
answered on 02 Sep 2015, 11:29 AM
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
0
Paul Grothe
Top achievements
Rank 1
answered on 02 Sep 2015, 12:50 PM

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.

0
Daniel
Telerik team
answered on 04 Sep 2015, 08:40 AM
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
Tags
Grid
Asked by
Paul Grothe
Top achievements
Rank 1
Answers by
Paul Grothe
Top achievements
Rank 1
Daniel
Telerik team
Share this question
or