Telerik blogs

As you probably know some of our controls support web service load on demand (a.k.a. client-side databinding). Also in ASP.NET MVC we can call controller actions via Ajax. In this blog post I will show you how to populate RadComboBox and RadTreeView on demand by using a controller action which returns JsonResult. Let's start with RadComboBox:

Configure RadComboBox for Load on Demand

I have added the RadComboBox control to the default Index.aspx view and configured it like this:

<telerik:RadComboBox runat="server" ID="RadComboBox1" EnableLoadOnDemand="true"
ShowMoreResultsBox="true" EmptyMessage="Type here ..." Height="200px">
<
WebServiceSettings Path="Home" Method="LoadItems" />
</telerik:RadComboBox>

The important thing here is that RadComboBox is configured as if it were using a web service - it will call the Home controller's LoadItems method. Internally RadComboBox us using ASP.NET Ajax to call the specified URL and populate from the returned JSON.

Passing JSON to Controller Methods

RadComboBox is passing a RadComboBoxContext object to web service methods. This object is used by the developer for various reasons - filtering, paging etc. Consider the following method:

[WebMethod]
public RadComboBoxData LoadItems(RadComboBoxContext context)
{
}

In a regular web service the context parameter would be automatically deserialized from the JSON passed by RadComboBox. In ASP.NET MVC you should deserialize the JSON parameter yourself. I did it by using a custom ActionFilter. Here is the implementation of the filter:

public class JsonParamFilter : ActionFilterAttribute
{
public string Param { get; set; }
public Type TargetType { get; set; }

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string contentType = filterContext.HttpContext.Request.ContentType;

if (string.IsNullOrEmpty(contentType))
return;

if (!contentType.Contains("application/json"))
return;

string paramValue;
using (var reader = new StreamReader(filterContext.HttpContext.Request.InputStream))
paramValue = reader.ReadToEnd();

var serializer = new JavaScriptSerializer();
var rawResult = (IDictionary<string, object>) serializer.DeserializeObject(paramValue);

var deserializeMethod = serializer.GetType()
.GetMethod("ConvertToType")
.MakeGenericMethod(TargetType);

filterContext.ActionParameters[Param] =
deserializeMethod.Invoke(serializer, new[] {rawResult[Param]});
}
}

Here is how to use it:

[JsonParamFilter(Param = "context", TargetType=typeof(RadComboBoxContext))]
public JsonResult LoadItems(RadComboBoxContext context)
{
}

Implementing the Load On Demand Method

There is only one thing left - to implement the method and return a RadComboBoxData object in JSON format. There is a tricky part though - ASP.NET Ajax expects a web service to return a JSON in this format: {d:{}}. This is easily done by returning an anonymous object with a single "d" property containing the desired result:

[JsonParamFilter(Param = "context", TargetType = typeof (RadComboBoxContext))]
public JsonResult LoadItems(RadComboBoxContext context)
{
RadComboBoxData result = new RadComboBoxData();
//fill the result return Json(new {d = result});
}

And that's it. RadComboBox has been successfully tricked that it is populated from a web service!

combobox 

Populating RadTreeView on Demand From MVC Controller Action

The implementation is exactly the same:

  1. Configure RadTreeView for web service load on demand
  2. <telerik:RadTreeView runat="server" ID="RadTreeView1">
    <WebServiceSettings Path="Home" Method="LoadNodes" />
    <
    Nodes>
    <telerik:RadTreeNode Text="Fuller" ExpandMode="WebService" />
    </Nodes>
    </telerik:RadTreeView>
  3. Decorate the controller action with the JsonParamFilter so the JSON parameter is automatically deserialized
  4. [JsonParamFilter(Param = "node", TargetType = typeof (RadTreeNodeData))]
    public JsonResult LoadNodes(RadTreeNodeData node)
    {
    }
  5. Implement the action method and return the result
  6. [JsonParamFilter(Param = "node", TargetType = typeof (RadTreeNodeData))]
    public JsonResult LoadNodes(RadTreeNodeData node)
    {
    List<RadTreeNodeData> result = new List<RadTreeNodeData>();

    //fill the result return Json(new {d = result.ToArray()});
    }
     

About the Author

Atanas Korchev

 is Team Leader in Kendo UI Team

Related Posts

Comments

Comments are disabled in preview mode.