Owin Selfhosting以流模式返回数据

时间:2018-01-08 10:31:08

标签: c# asp.net self-hosting

我是自主托管服务。我能够HttpGetHttPut个对象。现在我需要返回一个大文件(流)。我的问题是如何返回一个大流。

下面我将编写用于获取和保存测试类Customer的方法。

可能重复:

  • Selfhosting deal with large files。唉答案对我没有帮助,它声明:确保回复内容为StreamContent直到现在我还没有不需要写任何回复内容。我应该更改什么才能返回StreamContent
  • ASP.NET Web API 2 - StreamContent is extremely slow
    这个答案似乎描述了我的问题的解决方案。 HttpRequestMessage对象用于创建HttpResponseMessage对象。然后将StreamContent对象分配给HttpResponseMessage.Content。但是我在哪里获得HttpRequestMessage,我应该在签名中更改哪些内容才能返回HttpResponseMessage

所以副本对我没有帮助。答案给我留下了几个问题。

到目前为止,我可以使用[HttpGet][HttpPost]获取并保存对象。在下面的简化代码中,我得到并保存Customer

根据给定的描述y MSDN: Use OWIN to Self-Host ASP.NET

创建我的服务器

已安装的nuget Microsoft.AspNet.WebApi.OwinSelfHost

服务器端

public class Customer {...}

[RoutePrefix("test")]
public class MyTestController : ApiController
{
    [Rout("getcustomer")]
    [HttpGet]
    public Customer GetCustomer(int customerId)
    {
         Customer fetchedCustomer = ...;
         return fetchedCustomer;
    }

    [Route("SaveCustomer")
    [HttpPost]
    public void SaveCustomer(Customer customer)
    {
         // code to save the customer
    }
}

服务器端:主要

static void Main(string[] args)
{
    var owinserver = WebApp.Start("http://+:8080", (appBuilder) =>
    {
        HttpConfiguration config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Formatters.Remove(config.Formatters.XmlFormatter);

        appBuilder.UseWebApi(config);
        config.EnsureInitialized();
    });

    Console.WriteLine("Press any key to end");
    Console.ReadKey();
}

这足以获得和设置客户。显然,如果没有HttpRequestMessage,这是可能的。

所以我的问题:

  • 能够返回大流的函数的签名是什么?
  • 是否足以按照第二个副本中的建议分配StreamContent对象?

1 个答案:

答案 0 :(得分:0)

显然答案比我想象的要容易。

在我看到的示例中,HttpGet的返回值是您想要返回的对象:

[Route("getcustomer")]
[HttpGet]
public Customer GetCustomer(int customerId)
{
    Customer fetchedCustomer = ...
    return fetchedCustomer;
}

要返回流,请将返回值更改为HttpResponseMessage并使用要返回的流填充HttpRespnseMessage的内容:

[Route("getFileStream")]
[HttpGet]
public Customer GetFileStream(Guid fileId)
{
    // get the stream to return:
    System.IO.Stream myStream = ...
    // get the request from base class WebApi, to create an OK response
    HttpResponseMessage responesMessage = this.Request.CreateResponse(HttpStatusCode.OK);
    responseMessage.Content = new StreamContent(myStream);
    // use extra parameters if non-default buffer size is needed
    return responseMessage;
}

客户端:

public class MyOwinFileClient
{
    private readonly Owin.Client.WebApiClient webApiClient;

    // constructor:
    public MyOwinFileClient()
    {
        this.webApiClient = new Owin.Client.WebApiClient(... url);
    }

    // the function to get the stream:
    public async Task<Stream> GetFileStream(Guid fileId)
    {
        HttpClient myClient = ...
        string requestStreamUri = @"test\GetFileStream?fileId=" + fileId.ToString("N");
        HttpResponseMessage responseMessage = await httpClient.GetAsync(requestStreamUri)
            .ConfigureAwait(false);

        // throw exception if not Ok:
        if (!response.IsSuccessStatusCode)
        {
            string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            throw new System.Net.Http.HttpRequestException($"{response.StatusCode} [{(int)response.StatusCode}]: {content}");
        }

        // if here: success: convert response as stream:
        Stream stream = await response.Content.ReadAsStreamAsync()
            .ConfigureAwait(false);
        return stream;
    }
}

用法:

private async void Button1_clicked(object sender, EventArgs e)
{
     // download the stream that contains the Bitmap:
     Guid bitMapId = ...
     MyOwinFileClient myClient = new MyOwinFileClient();

     // get the stream:
     Stream stream = await myClient.GetFileStream(bitMapId);

     // assume the stream to be a bitmap:
     Bitmap bmp = new Bitmap(stream);
     this.pictureBox1.Image = bmp;
}

为简单起见,我省略了Dispose