Wednesday, December 21, 2011

kendoUI - adding menu using web service

kendoUI is still in the beginning stages. Eventhough they have a commercial version there is quite a bit of functionalities needed before it can be fully used for a large application.


I am not sure what is the best practice for using each control and I would like to know this myself from @Telerik.  But here is an example of how to populate the kendoMenu dynamically using a web-service.


General approach is that each control/widget on the page should get the data from web-service. That way there is no server request. Now, our web-service can internally get the data from anywhere (database, xml file or any other appropriate way.) There will be a question about menu based on user-rights. But let's save that for later.


#1 - for now, let's assume that we have a web-service that has a function like following to return the menu details. 

    [WebService] //(Namespace = "http://WebService/")
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    public class WebService : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public List GetMenu()
        {
            List items = new List();
            items.Add(new MenuItem() { ParentTitle = "", Title = "Home", Link = "default.aspx" });
            items.Add(new MenuItem() { ParentTitle = "", Title = "Edit", Link = "edit.aspx" });
            items.Add(new MenuItem() { ParentTitle = "", Title = "View", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Home", Title = "Login", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Home", Title = "Profile", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Home", Title = "Meetings", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Home", Title = "Logout", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Edit", Title = "Cut", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Edit", Title = "Copy", Link = "view.aspx" });
            items.Add(new MenuItem() { ParentTitle = "Edit", Title = "Paste", Link = "view.aspx" });
            return items;
        }



#2 - we can declare our MenuItem class having all possible properties that we want to make use of in the front-end. We may want to have some unique id, or type of menu etc. but below is a simpler form of such menu item class.
    public class MenuItem
    {
        public string ParentTitle { get; set; }
        public string Title { get; set; }
        public string Link { get; set; }
        public string IconUrl { get; set; }
    }

#3 - the html can be as simple as 

Tuesday, December 20, 2011

calling asp.net (asmx) web service from jquery .ajax()

There is lot of information out there on this very topic but I got errors while implementing it and finally fixed it. So I wanted to post my findings with example. 1) When you create .Net ASMX Web Service, it will look like following: 

 [WebService] //(Namespace = "http://WebService/") 
 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] 
[System.Web.Script.Services.ScriptService] 


 public class WebService : System.Web.Services.WebService 
 { 
 [WebMethod] 
  public string HelloWorld() 
 { 
 return "Hello World"; 
 }
}


Here the attribute in bold is very important. That indicates that this service can be called from the Javascript+ajax methods. 


You may see [ScriptMethod(ResponseFormat = ResponseFormat.Json)] attribute used for the Web-methods but this may not be necessary. At least when I ran the example I could run it successfully with and and without this attribute. Because the response format of the method will be determined based on the content-type used by the caller. Hence its important to set the 'content-type' from caller as below:


        $.ajax({
        type: 'POST',
            contentType: "application/json; charset=utf-8",
            url: 'http://localhost:1197/WebService.asmx/HelloWorld',
            dataType: "json",
            data: "{}",
            success: function(msg) {
                console.log(msg.d);
            },
            error: function(xhr, desc, ex) {
                console.log(xhr.responseText);
                console.log(desc);
                console.log(ex);
            }
        });

I was trying above example w/o 'contentType' and error function was called with 'parser error'. So having contentType in above is really important. 

Passing "{}" for data is not that important when your functions do not have any parameters. I could successfully call function w/o it, but if you get errors, you can try that.

Same for dataType: "json" - I commented it out and returned value was still interpreted as "json". I believe - again this is due to the contentType.