Owin Selfhosting return data in streamed mode

依然范特西╮ 提交于 2019-12-13 18:31:47

问题


I'm selfhosting a service. I'm able to HttpGet and HttPut objects. Now I need to return a large File(stream). My question is how to return a large stream.

Below I write the methods I use to get and save a test class Customer.

Possible duplicates:

  • Selfhosting deal with large files.
    Alas the answer doesn't help me, it states: make sure that the response content is a StreamContent. Until now I didn't need to write any response content. What should I change to return a StreamContent?
  • ASP.NET Web API 2 - StreamContent is extremely slow
    This answer seems to describe the solution to my problem. A HttpRequestMessage object is used to create a HttpResponseMessage object. Then a StreamContent object is assigned to the HttpResponseMessage.Content. But where do I get a HttpRequestMessage, and what should I change in my signatures to be able to return a HttpResponseMessage?

So the duplicates do not help me enough. The answer leave me with a several question.

Until now I'm able to Get and Save an object using a [HttpGet] and [HttpPost]. In my simplified code below I get and save a Customer

To create my server according to the description given y MSDN: Use OWIN to Self-Host ASP.NET

Installed nuget: Microsoft.AspNet.WebApi.OwinSelfHost

Server Side

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

Server side: Main

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

This is enough to get and set a customer. Apparently this is possible without a HttpRequestMessage.

So my questions:

  • What is the signature of a function to be able to return a big stream?
  • Is it enough to assign the StreamContent object as is proposed in the second duplicate?

回答1:


Apparently the answer is easier than I thought.

In the examples I saw, the return value of a HttpGet was the object that you wanted to return:

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

To return a stream, change the return value to a HttpResponseMessage and fill the Content of the HttpRespnseMessage with the Stream you want to return:

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

Client side:

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

Usage:

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

For simplicity I left out Dispose



来源:https://stackoverflow.com/questions/48148435/owin-selfhosting-return-data-in-streamed-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!