Question

I am building a restful service in C# using service stack.

Here is my service implementation.

namespace cloudfileserver
{   
    [Route("/updatefile", "POST")]
    public class UpdateFile
    {
        public UserFile file { get; set; }
    }

    public class CloudFileService : Service
    {
        public InMemoryFileSystem filesystem { get; set; }
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger (typeof(CloudFileService));

        public void Post (UpdateFile request)
        {
            try{
                logger.Debug("File received is :"  + request.file);
                filesystem.addFileSynchronized (request.clientId, request.file);
            }catch(Exception e){
                logger.Debug(e);
                throw e;
            }
        }
    }
}

I am calling this service through the following servicestack client code :

JsonServiceClient client  = new JsonServiceClient(ENDPOINT);
UpdateFile arg = new UpdateFile();
UserFile file = new UserFile ("x.txt", "piyush");
file.SetFileContent (getByteArrayFromString ("Filecontent"), 0);
arg.file = file;
client.Post<Object>("/updatefile", arg);

The issue is that whenever I make a post call through the above client code, the file object received is NULL on the server end (which I verify by writing it to the log file).

Here is the File class which is being sent over the wire. The File class is serialisable since I can correctly send it through a GET call.

Any idea what might be going wrong here?

Was it helpful?

Solution

I have tested your scenario, and can't reproduce the issue you are having. I would recommend you verify your SetFileContent method and the getByteArrayFromString method, as you may have an error there. Feel free to post that implementation.

Further to that it would be useful if you captured the HTTP request that is made to the server, to determine where the problem lies.

Below is the fully working source code for a self-hosted ServiceStack v4 test application, that uses the implementation you outlined, I hope this helps.

using System;
using ServiceStack;
using System.Collections.Generic;

namespace v4
{
    class MainClass
    {
        // Assumed implementation of your getByteArrayFromString
        static byte[] getByteArrayFromString(string path)
        {
            return System.IO.File.ReadAllBytes(path);
        }

        public static void Main()
        {
            // Simple Self-Hosted Console App
            var appHost = new AppHost(500);
            appHost.Init();
            appHost.Start("http://*:9000/");

            // Test the service
            string filename = "image.png";
            JsonServiceClient client  = new JsonServiceClient("http://localhost:9000");

            // Create and set the file contents
            UserFile file = new UserFile (filename, "username");
            file.SetFileContent(getByteArrayFromString(filename), 0);

            // Post the file
            client.Post<Object>("/updatefile", new UpdateFile { file = file } );

            Console.ReadKey();
        }
    }

    public class AppHost : AppHostHttpListenerPoolBase
    {
        public AppHost(int poolSize) : base("Test Service", poolSize, typeof(TestService).Assembly) { }
        public override void Configure(Funq.Container container) { }
    }

    [Route("/updatefile","POST")]
    public class UpdateFile
    {
        public UserFile file { get; set; }
    }

    [Serializable]
    public class UserFile 
    {

        public string filepath { get; set;}
        public string owner { get; set;}
        public byte[] filecontent { get; set;}
        public long filesize { get; set;}
        public List<string> sharedwithclients { get; set;}
        public long versionNumber {get;set;}
        object privateLock = new object();

        public UserFile (string filepath, string owner)
        {      
            this.filepath = filepath;
            this.owner = owner;
            versionNumber = -1;
            filesize = 0;
            filecontent = new byte[0];
            sharedwithclients = new List<string>();
        }

        public void SetFileContent(byte[] contents, long version)
        {
            filecontent = contents;
            filesize = filecontent.Length;
            versionNumber = version;
        }
    }

    public class TestService : Service
    {
        public void Post(UpdateFile request)
        {
            // Request is populated correctly i.e. not null.
            Console.WriteLine(request.file.ToJson());
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top