【问题标题】:Serialized object POST'd using the ServiceStack client is null使用 ServiceStack 客户端 POST 的序列化对象为空
【发布时间】:2014-04-30 16:16:20
【问题描述】:

我正在使用服务堆栈在 C# 中构建一个宁静的服务。

这是我的服务实现。

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;
            }
        }
    }
}

我正在通过以下 servicestack 客户端代码调用此服务:

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);

问题是每当我通过上述客户端代码进行 post 调用时,在服务器端收到的文件对象为 NULL(我通过将其写入日志文件来验证)。

Here is the File class 正在通过网络发送。 File 类是 serialisable,因为我可以通过 GET 调用正确地发送它。

知道这里可能出了什么问题吗?

【问题讨论】:

    标签: c# rest servicestack


    【解决方案1】:

    我已经测试了您的方案,但无法重现您遇到的问题。我建议您验证您的 SetFileContent 方法和 getByteArrayFromString 方法,因为那里可能有错误。随意发布该实现。

    此外,如果您捕获向服务器发出的 HTTP 请求,这将有助于确定问题所在。

    以下是自托管 ServiceStack v4 测试应用程序的完整源代码,它使用您概述的实现,希望对您有所帮助。

    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());
            }
        }
    }
    

    【讨论】:

    • 感谢您的回复斯科特。即使 SetFileContent(它只是一个 setter 方法)和 getByteArrayFromString 存在一些问题,也会影响文件类的成员。问题是正在接收的文件对象为空。此外,当您发送 UpdateFile 对象时,我直接在我的 post call 中发送文件对象。有区别吗?
    • @Piyush 没有设置new UpdateFile { file = file } 或使用你的args 对象没有任何区别。我在那里的示例代码有效。所以你的实现有些奇怪。你可以尝试运行它,看看它是否有效。只需创建一个新的控制台应用程序,添加 ServiceStack 包并从上面复制代码。将名为 image.png 的文件放在 bin 文件夹中,或将代码中的文件路径指向有用的地方。或者,正如我提到的,您可以使用 HTTP 监控工具(例如 fiddler)进行调试。
    • @Piyush 另外,您使用的是什么版本的 ServiceStack,即 4.019?你在本地测试吗?您正在测试的文件有多大,您使用代理吗?任何其他相关配置信息。
    • @Piyush 你搞定了吗?如果不是,如果您能提供更多信息,我可以尝试关闭此问题。
    • 非常感谢斯科特,它现在似乎可以正常工作了。你可以关闭。虽然我不太确定之前出了什么问题。如果我发现我会更新这个帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多