如何将大型类型从REST服务器传输到控制器

时间:2014-03-18 22:02:36

标签: c# json asp.net-mvc-4

我想就从#" REST"传输自定义对象的最佳方法提出一些建议。服务器到控制器。简而言之,我们在处理HttpGet请求的服务器上运行MVC 4。最初,通过将我们的自定义类序列化为JSON,然后将它们反序列化为客户端大小,可以适应服务器的所有响应。但是,现在我们需要传输大数据(即图像),这种方法不再适用。

以下是我目前正在做的精简版本,但我想就更好的方式传输大文件(自定义类型)提出一些建议。

类:

[Serializable]
public class TradingPost
{
    public int TradingPostId { get; set; }
    public string UserId { get; set; }        
}

[Serializable]
public class TradingPostImage
{
    public int TradingPostImageId { get; set; }
    public string ImageName { get; set; }
    public string ImageData { get; set; }
}

[Serializable]
public class TradingPostWithImages
{
    public TradingPost Post { get; set; }
    public List<TradingPostImage> Images { get; set; }

    public TradingPostWithImages()
    {
        Post = new TradingPost();
        Images = new List<TradingPostImage>();
    }
}

服务器端控制器:

[HttpGet]
    public ActionResult GetAllTradingPosts()
    {            
        List<TradingPostWithImages> postsAndImages = PostRepository.GetAllPostsAndImages();

        MemoryStream memoryStream = new MemoryStream();
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, postsAndImages);

        var postsAsByteArray = memoryStream.ToArray();

        return File(postsAsByteArray, "application/octet-stream");              
    }

客户端控制器:

public List<TradingPostWithImages> GetItems()
    {
        var dataGatewayPath = GetGateWayPath("GetTradingPosts");

        MemoryStream webData = new MemoryStream();

        var Request = WebRequest.CreateHttp(dataGatewayPath );
        var Response = Request.GetResponse() as HttpWebResponse;

        if(Response != null)
        {
             DataStream = Response.GetResponseStream();

             if(DataStream != null)
             {
                    DataStream.CopyTo(webData);
                    DataStream.Close();
             }

             Response.Close();
        }

        webData.Position = 0;
        BinaryFormatter formatter = new BinaryFormatter();

        var activeItems = (List<TradingPostWithImages>)formatter.Deserialize(webData);

        return activeItems;
    }

这样可行,但有没有办法可以在不反序列化流然后将其转换为自定义类型的情况下完成我的目标?是否有更好或更有效的方法来完成我的任务?

1 个答案:

答案 0 :(得分:1)

要根据评论中的某些对话直接回答您的问题,实际上,我唯一可以建议您采用延迟加载类型的方法。通常,使用延迟加载,您可以根据需要加载数据,但在这种情况下,将立即需要所有数据,但这个想法是一样的。因此,我建议的最有效的方法是首先加载所有简单数据(基本上数据传输相当快,除了你的图像,这几乎是所有东西)。我认为你不会比通过http的字节流更有效率(也许可以试试UDP ??),因此可以通过用户感知来调整性能。

如果您的视图层是一个网页,那么您可以首先渲染所有基本对象数据,方法是在第一次调用时引用瘦对象中的图像ID(而不是发送带有图像数据的胖对象),然后将这些ID用于图像标记,然后调用内容操作,该操作将使用该id异步地从服务器检索图像数据。这样,即使图像加载,您的页面也可以使用。像这样:

enter image description here

如果您的视图图层类似于winforms应用程序,则可以执行大致相同的操作。我们的想法是,在将图像加载到不同的线程上时,立即检索并显示简单数据,从而保持UI响应。只需显示某些加载指示器即可显示图像。

IMO,当通过HTTP进行大量文件传输时,您可以做到这一点,以创造性地提高效率。它更多的是处理具有重试逻辑的中断连接(恢复下载,通过字节偏移等)并保持UI响应而不是其他任何东西。只要在没有用户感觉应用程序被锁定的情况下进行可见的进展,就应该减轻由那些漫长的加载时间引起的负面体验。

除了这种消息传递策略之外,我还要研究流媒体技术。本文可能有所帮助:WebAPI Request Streaming support