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

Bind problem using JSONP and KendoUI ListView

5 Answers 193 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Søren Hartig
Top achievements
Rank 2
Søren Hartig asked on 06 Dec 2012, 11:58 AM
Hello there,

I'm getting pretty frustrated. I have been trying to get my RESTful WCF service to work with the ListView controller. I was reusing the code from the demo (http://demos.kendoui.com/web/listview/editing.html) and adjusting it to my own needs. I have googled for help on how to enable my service to support JSONP, even though in my test bench I execute it locally.

I have a webservice that produces this JSON output:
[{"Id":"acd34cd2-4500-4e2e-988d-2f71738cb7b6","Name":"Plan 1","NextRun":"06-01-2013 04:43:55","NoOfJobs":7,"Status":0},{"Id":"5431e4ef-943c-4bcb-b747-378416face14","Name":"Plan 2","NextRun":"13-04-2013 03:23:02","NoOfJobs":7,"Status":0},{"Id":"ab9ce9ea-c9d1-4f90-be36-b6aca23c247d","Name":"Plan 3","NextRun":"09-12-2012 13:11:04","NoOfJobs":7,"Status":0},{"Id":"93b4689b-d39c-45fa-979a-93148dd81978","Name":"Plan 4","NextRun":"05-01-2013 18:56:21","NoOfJobs":7,"Status":0},{"Id":"61e89143-e6d6-4d3b-9c06-88509c2c9b55","Name":"Plan 5","NextRun":"06-03-2013 03:03:07","NoOfJobs":7,"Status":0},{"Id":"877244ee-3a63-4733-8f3e-a8154ab5b04c","Name":"Plan 6","NextRun":"05-02-2013 00:17:46","NoOfJobs":7,"Status":0}]

The webservice looks like this:
[ServiceContract]
    public interface IPlanListRESTService
    {
        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "fillplanlist/{count}")]
        List<Plan> FillPlanList(string count);

        [OperationContract]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "plan")]
        bool AddPlan(Plan plan);

        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "planlist")]
        List<Plan> GetPlanList();

        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "xml/{id}")]
        string XMLData(string id);

        [OperationContract]
        [WebInvoke(Method   = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "json/{id}")]
        string JSONData(string id);
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PlanListRESTService : IPlanListRESTService
    {

        List<Plan> planList = new List<Plan>();
        static Random rand = new Random();

        public List<Plan> FillPlanList(string count)
        {
            try
            {
                int noOfPlans= Convert.ToInt32(count);

                if ((noOfPlans < 0) || (noOfPlans > 25))
                    return planList;

                planList.Clear();

                for (int i = 1; i <= noOfPlans; i++)
                {
                    Plan plan = new Plan();

                    plan.Id = Guid.NewGuid().ToString();
                    plan.Name = "Plan " + i.ToString();
                    plan.Status = PlanStatus.Waiting;

                    Random random = new Random();
                    plan.NoOfJobs = random.Next(0, 8);

                    plan.NextRun = GetRandomDate(new DateTime(2012, 11, 1), new DateTime(2013, 5, 1));

                    planList.Add(plan);
                }

                return planList;
            }
            catch (Exception)
            {
                return planList;
            }
        }

        public bool AddPlan(Plan plan)
        {
            plan.Id = Guid.NewGuid().ToString();
            planList.Add(plan);

            return true;
        }

        public List<Plan> GetPlanList()
        {
            return planList;
        }

        public string XMLData(string id)
        {
            return "You requested product " + id;
        }

        public string JSONData(string id)
        {
            return "You requested product " + id;
        }

        public string ToJSon(object obj)
        {
            JavaScriptSerializer oSerializer = new JavaScriptSerializer();
            return oSerializer.Serialize(obj);
        }

        public string GetRandomDate(DateTime dtStart, DateTime dtEnd)
        {
            int cdayRange = (dtEnd - dtStart).Days;

            return dtStart.AddDays(rand.NextDouble() * cdayRange).ToString();
        }
    }

The web.config for the service looks like this:
<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="PlanListRESTService.PlanListRESTService" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" binding="webHttpBinding"
                  bindingConfiguration="webHttpBindingWithJsonP"
                  contract="PlanListRESTService.IPlanListRESTService"
                  behaviorConfiguration="Web"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="Web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

And finally here is the Index.cshtml file that should render the listview with my data, but it doesn't :-( :
@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
<div id="example" class="k-content">
    <div class="k-toolbar k-grid-toolbar">
        <a class="k-button k-button-icontext k-add-button" href="#"><span class="k-icon k-add"></span>Add new plan</a>
    </div>
    <div id="listView"></div>

    <div id="pager" class="k-pager-wrap">
    </div>

    <script type="text/x-kendo-tmpl" id="template">
        <div class="plan-view">
            <dl>
                <dt>Name</dt>
                <dd>${Name}</dd>
                <dt>No. of jobs</dt>
                <dd>${NoOfJobs}</dd>
                <dt>Next run:</dt>
                <dd>${NextRun}</dd>
                <dt>Status</dt>
                <dd>${Status}</dd>
            </dl>
            <div class="edit-buttons">
                <a class="k-button k-button-icontext k-edit-button" href="\\#"><span class="k-icon k-edit"></span>Edit</a>
                <a class="k-button k-button-icontext k-delete-button" href="\\#"><span class="k-icon k-delete"></span>Delete</a>
            </div>
        </div>
    </script>

    <script type="text/x-kendo-tmpl" id="editTemplate">
        <div class="plan-view">
            <dl>
                <dt>Plan Name</dt>
                <dd>
                    <input type="text" data-bind="value:Name" name="Name" required="required" validationMessage="required" />
                    <span data-for="Name" class="k-invalid-msg"></span>
                </dd>
                <dt>No. of jobs</dt>
                <dd>
                    <input type="text" data-bind="value:NoOfJobs" data-role="numerictextbox" data-type="number" name="NoOfJobs" required="required" min="0" validationMessage="required" />
                    <span data-for="NoOfJobs" class="k-invalid-msg"></span>
                </dd>
                <dt>Status</dt>
                <dd>
                    <input type="text" data-bind="value:Status" name="Status" required="required" data-type="number" min="0" validationMessage="required" />
                    <span data-for="Status" class="k-invalid-msg"></span>
                </dd>
                <dt>Next run</dt>
                <dd>
                    <input type="text" data-bind="value:NextRun" name="NextRun" required="required" data-type="number" min="0" validationMessage="required" />
                    <span data-for="NextRun" class="k-invalid-msg"></span>
                </dd>
            </dl>
            <div class="edit-buttons">
                <a class="k-button k-button-icontext k-update-button" href="\\#"><span class="k-icon k-update"></span>Save</a>
                <a class="k-button k-button-icontext k-cancel-button" href="\\#"><span class="k-icon k-cancel"></span>Cancel</a>
            </div>
        </div>
    </script>

    <script>
        $(document).ready(function () {
            var crudServiceBaseUrl = "http://localhost:8080/PlanListRESTService",
                dataSource = new kendo.data.DataSource({
                    transport: {
                        read:  {
                            url: crudServiceBaseUrl + "/fillplanlist/20",
                            dataType: "jsonp"
                        },
                        //update: {
                        //    url: crudServiceBaseUrl + "/fillplanlist/20",
                        //    dataType: "jsonp"
                        //},
                        //destroy: {
                        //    url: crudServiceBaseUrl + "/fillplanlist/20",
                        //    dataType: "jsonp"
                        //},
                        //create: {
                        //    url: crudServiceBaseUrl + "/fillplanlist/20",
                        //    dataType: "jsonp"
                        //},
                        parameterMap: function(options, operation) {
                            if (operation !== "read" && options.models) {
                                return {models: kendo.stringify(options.models)};
                            }
                        }
                    },
                    batch: true,
                    pageSize: 6,
                    schema: {
                        model: {
                            id: "Id",
                            fields: {
                                Id: { editable: false, nullable: true },
                                Name: "Name",
                                NextRun: "Next run",
                                NoOfJobs: { type: "number" },
                                Status: { type: "number" }
                    }
                        }
                    }
                });


            $("#pager").kendoPager({
                dataSource: dataSource
            });

            var listView = $("#listView").kendoListView({
                dataSource: dataSource,
                template: kendo.template($("#template").html()),
                editTemplate: kendo.template($("#editTemplate").html())
            }).data("kendoListView");

            $(".k-add-button").click(function(e) {
                listView.add();
                e.preventDefault();
            });
        });
    </script>
    <style scoped>
        .plan-view
        {
            float: left;
            width: 300px;
            margin: 5px;
            padding: 3px;
            -moz-box-shadow: inset 0 0 50px rgba(0,0,0,0.1);
            -webkit-box-shadow: inset 0 0 50px rgba(0,0,0,0.1);
            box-shadow: inset 0 0 50px rgba(0,0,0,0.1);
            border-top: 1px solid rgba(0,0,0,0.1);
            -webkit-border-radius: 8px;
            -moz-border-radius: 8px;
            border-radius: 8px;
        }

        .plan-view dl
        {
            margin: 10px 0;
            padding: 0;
            min-width: 0;
        }
        .plan-view dt, dd
        {
            float: left;
            margin: 0;
            padding: 0;
            height: 30px;
            line-height: 30px;
        }
        .plan-view dt
        {
            clear: left;
            padding: 0 5px 0 15px;
            text-align: right;
            opacity: 0.6;
            width: 100px;
        }
        .k-listview
        {
            border: 0;
            padding: 0;
            min-width: 0;
        }
        .k-listview:after, .plan-view dl:after
        {
            content: ".";
            display: block;
            height: 0;
            clear: both;
            visibility: hidden;
        }
        .edit-buttons
        {
            text-align: right;
            padding: 5px;
            min-width: 100px;
            border-top: 1px solid rgba(0,0,0,0.1);
            -webkit-border-radius: 8px;
            -moz-border-radius: 8px;
            border-radius: 8px;
        }

        .k-toolbar, #listView, .k-pager-wrap
        {
            width: 960px;
            /*margin: 0 auto;*/
            -webkit-border-radius: 11px;
            -moz-border-radius: 11px;
            border-radius: 11px;
        }
        #listView
        {
            width: 960px;
        }
        span.k-invalid-msg
        {
            position: absolute;
            margin-left: 160px;
            margin-top: -26px;
        }
    </style>
</div>

<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>

<p>
    To learn more about working with the Kendo UI Complete for ASP.NET MVC, you can visit the folowing resources:
</p>
<ul>
        <li><a href="http://demos.kendoui.com/">online demos</a></li>
        <li><a href="http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/introduction">online documentation</a></li>
        <li><a href="http://www.kendoui.com/forums.aspx">community forums</a></li>
        <li><a href="http://tv.telerik.com/search?FilterByTags=KendoUI">videos on Telerik TV</a></li>
</ul>

Help me please

5 Answers, 1 is accepted

Sort by
0
Søren Hartig
Top achievements
Rank 2
answered on 10 Dec 2012, 01:58 PM
Anyone, I'm really stuck here :-(
0
Daniel
Telerik team
answered on 10 Dec 2012, 04:44 PM
Hello,

The code looks correct. Are there any JavaScript errors thrown? What is the response from the server when JSONP is enabled? It would be helpful if you could send a sample project so I can investigate what exactly is going wrong.

Kind regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Søren Hartig
Top achievements
Rank 2
answered on 11 Dec 2012, 08:20 AM
Hi Daniel.

Thank you for your answer. It is impossible for me to attach a sample solution at the size of 2MB or smaller.
Which part of my solution do you want ? You can see the code for my RESTful service, the web.config.
I host the service from a windows service via the OnStart and OnStop events. The web application is a KendoUI
MVC 4 project with modified source code from the demo (as I mentioned before).

Thanks in advance...

0
Søren Hartig
Top achievements
Rank 2
answered on 13 Dec 2012, 10:44 AM
Hi Daniel,

I have compressed my VS 2012 solution to approx. 14 MB. That is the best I can do.
Is there a mail-address I can mail it to ? 

I'm about to ditch the whole KendoUI thing, but I'm giving it a last go.

I would really like you to take a look at it before I find an alternative solution.

0
Daniel
Telerik team
answered on 13 Dec 2012, 10:54 AM
Hi again,

The service response should indicate whether the callback was added or not. As I mentioned in my previous reply the code looks correct. I am attaching a sample project with similar setup which seems to work correctly on my side. Let me know if it works on yours.

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
ListView
Asked by
Søren Hartig
Top achievements
Rank 2
Answers by
Søren Hartig
Top achievements
Rank 2
Daniel
Telerik team
Share this question
or