REST error

rated by 0 users
Answered (Verified) This post has 1 verified answer | 14 Replies | 2 Followers

Not Ranked
Male
25 Posts
Points 380
Eudoxus posted on Fri, Oct 3 2008 6:58 AM

Hi,

Could someone help me in interpretting this error, please?  I'm using the CommunityServer.WebServices.DLL API to access the localhost/cs/blogs/BlogService.asmx.

I use the following code to try to retrieve the TTV blog:

using CommunityServer.WebServices.Blogs;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        BlogsService service = new BlogsService("http://localhost/cs/blogs/BlogService.asmx", "TestUser", "3ne1xps7");
       
        g1.DataSource = service.GetBlog("TTV");
        g1.DataBind();
    }
}

But all I get is the following error:

 

Server Error in '/TestCSWs' Application.
Unable to deserialize object from response body of type CommunityServer.WebServices.Serialization.Blogs.BlogSerialized
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Unable to deserialize object from response body of type CommunityServer.WebServices.Serialization.Blogs.BlogSerialized

Source Error:

Line 14:         BlogsService service = new BlogsService("http://localhost/cs/blogs/BlogService.asmx", "TestUser", "3ne1xps7");
Line 15:        
Line 16:         g1.DataSource = service.GetBlog("TTV");
Line 17:         g1.DataBind();
Line 18:     }


Source File: c:\Personal2008\TestCSWs\Default.aspx.cs    Line: 16

Stack Trace:

[NullReferenceException: Unable to deserialize object from response body of type CommunityServer.WebServices.Serialization.Blogs.BlogSerialized]
   CommunityServer.WebServices.Serialization.Common.Response.GetResponseObject() +236
   CommunityServer.WebServices.Blogs.BlogsService.GetBlog(String blogKey) +137
   _Default.Page_Load(Object sender, EventArgs e) in c:\Personal2008\TestCSWs\Default.aspx.cs:16
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +50
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Answered (Verified) Verified Answer

Not Ranked
Male
25 Posts
Points 380
Verified by Eudoxus

Ok, having looked around and investigated the api reference I decided to write my own rest service caller.  This seems to work fine, provided you can handle the output data yourself.  As the work is done almost completely in the one method, a little modification would be required to get the dataset, xml or whatever out.  However, it's not difficult to request the specific data you want and then perhaps XSLT transform it to HTML and render it directly on the page, without wrapping it in a C# API first.  This is the code as I have it, so please forgive any unclean naming - it's all test/dev...

    private void Part4(string url, string reqData)

    {

        WebRequest req = WebRequest.Create(url);

        req.Credentials = CredentialCache.DefaultCredentials;

 

        //((HttpWebRequest)req).UserAgent = ".NET Framework Example Client";

        // add header to authorise

        req.Headers.Add("Rest-User-Token: " + EncodeTo64("3ne1xps7:Ejaz H Arain"));

        // add impersonation header to appear as a user (not the admin user used to access the api)

        //req.Headers.Add("Rest-Impersonate-User: jsmith");

 

        req.Method = String.IsNullOrEmpty(reqData) ? "GET" : "POST";

        req.ContentType = "text/xml";

 

        // provide content for POST request, if necessary

        req.ContentLength = (reqData ?? "").Trim().Length;

        if (req.Method != "GET")

        {

            Stream dataStream = req.GetRequestStream();

            byte[] arr = new ASCIIEncoding().GetBytes(reqData);

            dataStream.Write(arr, 0, arr.Length);

            dataStream.Close();

        }

 

        // get response from server

        WebResponse webResponse = req.GetResponse();

        StreamReader reader = new StreamReader(webResponse.GetResponseStream());

 

        // display the content

        string responseFromServer = reader.ReadToEnd();

 

        // clean up the streams

        reader.Close();

        webResponse.Close();

 

        // bind xml to dataset and print out in textarea

        DataSet set = new DataSet();

        set.ReadXml(new StringReader(responseFromServer));

        g1.DataSource = set;

        g1.DataBind();

 

        scripted.Text = responseFromServer;

 

        // repopulate the dropdown list of tables

        tableindex.DataSource = set.Tables;

        tableindex.DataBind();

 

        //Response.Output.Write(responseFromServer);

 

        // end response of this page

        //Response.End();

    }

 

    static public string EncodeTo64(string toEncode)

    {

        byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);

        string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);

        return returnValue;

    }

 

    static public string DecodeFrom64(string encodedData)

    {

        byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);

        string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);

        return returnValue;

    }

 

  • | Post Points: 5

All Replies

Not Ranked
13 Posts
Points 260
x893 replied on Sat, Oct 4 2008 5:01 AM

As i see in code your server response empty body

public T GetResponseObject<T>()
{
 object obj = Serializer.ConvertToObject(this.Body, typeof(T));
 if (obj == null)
  throw new NullReferenceException("Unable to deserialize object from response body of type " + typeof(T).FullName);
 return (T) obj;
}

Check you site configuration and response body

 

  • | Post Points: 20
Not Ranked
Male
25 Posts
Points 380

Sorry, but what are you asking me to do?  I've checked the configuration of my client and it's correct.  I've enabled the REST service on the server - I've also tried calling the same service on the dev.communityserver.com site with no joy.

What should I be looking for?  Is there something in the client or the server that needs enabling/activating/setting that isn't obvious?

Thanks,

Matt.

  • | Post Points: 20
Not Ranked
13 Posts
Points 260
x893 replied on Mon, Oct 6 2008 3:16 PM

I can't say about any recepts to you because CS.Webservices and CS.WebServices.Service dll obfuscate. Unofficial way is reflect this dll and use Visual studio debugger to find error.

 

  • | Post Points: 20
Not Ranked
Male
25 Posts
Points 380

So the web services are working fine for you?

Does anyone else have the problem I'm having - cos so far it seems I'm the only one! :(

m

  • | Post Points: 20
Not Ranked
17 Posts
Points 230

For accessing the REST Api, I think this line is wrong in your code:

 BlogsService service = new BlogsService("http://localhost/cs/blogs/BlogService.asmx", "TestUser", "3ne1xps7");

I think that  "http://localhost/cs/blogs/BlogService.asmx" should point to the root instead of this page, so it would be only "http://localhost" if that is where the community site is located.

- Edgar Dorn

Software Consultant

  • | Post Points: 20
Not Ranked
Male
25 Posts
Points 380

Thanks...

Any chance of an example piece of code (the examples at ), or perhaps some direct REST client code?

M

  • | Post Points: 20
Not Ranked
17 Posts
Points 230

well, not sure what you are looking for as sample code, but here is an example of making a call to retrieve all blogs. Do note that the source is in VB.Net, not C#:


blogService = New BlogsService(communityServerUrl, apiUser, apiKey, currentUser)
Dim blogList As List(Of Blog)
blogList = blogService.GetBlogs()

where communityServerUrl = the root location of your server. The client appends the proper URL to the end of the path, so going by your example, it would be http://localhost/

 

- Edgar Dorn

Software Consultant

  • | Post Points: 20
Not Ranked
Male
25 Posts
Points 380

Ok, thanks for your help, but it seems as though that's the code I was already using.  I've transposed it to C# to create this...

        BlogsService blogService = new BlogsService("http://localhost/", "matt", "3ne1xps7");
        List<Blog> blogList = blogService.GetBlogs();

But I'm still getting this error...

Unable to deserialize object from response body of type CommunityServer.WebServices.Serialization.Blogs.BlogListSerialized

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Unable to deserialize object from response body of type CommunityServer.WebServices.Serialization.Blogs.BlogListSerialized

Source Error:

Line 45:     {
Line 46: BlogsService blogService = new BlogsService("http://localhost/", "matt", "3ne1xps7");
Line 47: List<Blog> blogList = blogService.GetBlogs();
Line 48: g1.DataSource = blogList;
Line 49: g1.DataBind();

Source File: c:\Personal2008\TestCSWs\Default.aspx.cs    Line: 47

  • | Post Points: 20
Not Ranked
Male
25 Posts
Points 380
Verified by Eudoxus

Ok, having looked around and investigated the api reference I decided to write my own rest service caller.  This seems to work fine, provided you can handle the output data yourself.  As the work is done almost completely in the one method, a little modification would be required to get the dataset, xml or whatever out.  However, it's not difficult to request the specific data you want and then perhaps XSLT transform it to HTML and render it directly on the page, without wrapping it in a C# API first.  This is the code as I have it, so please forgive any unclean naming - it's all test/dev...

    private void Part4(string url, string reqData)

    {

        WebRequest req = WebRequest.Create(url);

        req.Credentials = CredentialCache.DefaultCredentials;

 

        //((HttpWebRequest)req).UserAgent = ".NET Framework Example Client";

        // add header to authorise

        req.Headers.Add("Rest-User-Token: " + EncodeTo64("3ne1xps7:Ejaz H Arain"));

        // add impersonation header to appear as a user (not the admin user used to access the api)

        //req.Headers.Add("Rest-Impersonate-User: jsmith");

 

        req.Method = String.IsNullOrEmpty(reqData) ? "GET" : "POST";

        req.ContentType = "text/xml";

 

        // provide content for POST request, if necessary

        req.ContentLength = (reqData ?? "").Trim().Length;

        if (req.Method != "GET")

        {

            Stream dataStream = req.GetRequestStream();

            byte[] arr = new ASCIIEncoding().GetBytes(reqData);

            dataStream.Write(arr, 0, arr.Length);

            dataStream.Close();

        }

 

        // get response from server

        WebResponse webResponse = req.GetResponse();

        StreamReader reader = new StreamReader(webResponse.GetResponseStream());

 

        // display the content

        string responseFromServer = reader.ReadToEnd();

 

        // clean up the streams

        reader.Close();

        webResponse.Close();

 

        // bind xml to dataset and print out in textarea

        DataSet set = new DataSet();

        set.ReadXml(new StringReader(responseFromServer));

        g1.DataSource = set;

        g1.DataBind();

 

        scripted.Text = responseFromServer;

 

        // repopulate the dropdown list of tables

        tableindex.DataSource = set.Tables;

        tableindex.DataBind();

 

        //Response.Output.Write(responseFromServer);

 

        // end response of this page

        //Response.End();

    }

 

    static public string EncodeTo64(string toEncode)

    {

        byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);

        string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);

        return returnValue;

    }

 

    static public string DecodeFrom64(string encodedData)

    {

        byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);

        string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);

        return returnValue;

    }

 

  • | Post Points: 5
Top 10 Contributor
5,284 Posts
Points 49,035
CS Developers

For the "unable to deserialize object" error, it usually best to hit the URL directly in the browser.  Right now, the client API doesn't do the best job of handling errors returned by the service.  It is failing to deserialize a BlogListSerialized because the service returned an error message instead of the blog list.  So this is error is only covering up the actual response message.

In this case, you could manually hit http://localhost/api/blogs.ashx/blogs and see what you get.

Un upcoming release will have better handling for the responses.

  • | Post Points: 20
Not Ranked
31 Posts
Points 545

I am getting problems after problems. Has it worked for anyone with win auth (AD integrated)?

  • | Post Points: 35
Top 25 Contributor
1,160 Posts
Points 70,020
CS Developers

Sorry to hear your frustrations musa4cs; many people are able to use the REST api for their needs, but I agree there are some rough edges. 

By 1.0 I assume you are referring to Community Server Evolution 1.0. 

REST infact was designed and released with Community Server 2008, there were no additions or customizations for the Evolution Product.

One big challenge with the REST API client library we made for C# was its facility to capture and bubble up meaningful error messages.  The server side API will often display a human readable error message, but this wont cast into the appropriate type for the client api...  As Ken mentions, you will get a Type error.  Often opening the actual endpoint page in a browser will show you the error (of course this only works for GET requests)

I believe the product team was going to publish the code for the client library, if that code is available it will be much easier to troubleshoot as you can get access to the actual client response as a string before the cast.

Dan

  • | Post Points: 20
Not Ranked
31 Posts
Points 545

Thanks for your help. I think the difficulty depends on the environment set up as well.

Frustration comes in when I try to make things work in a limited number of hours.

Anyway, it is finally working for me though comments don't appear right away due to caching issue.

But it is working at least. Thanks again.

 

  • | Post Points: 5
Top 10 Contributor
5,284 Posts
Points 49,035
CS Developers

When using the service with a site running Windows Authentication, you need to set the NetworkCredentials on the service object.  This is done the same as a normal HttpWebRequest and needs to be set for each instance of the service.

  • | Post Points: 5
Page 1 of 1 (15 items) | RSS
Powered by Community Server (Commercial Edition), by Telligent Systems

Copyright© 2008 Telligent Systems Inc. All rights reserved
CommunityServer.com  •  Telligent.com