问题
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 aStreamContent
. Until now I didn't need to write any response content. What should I change to return aStreamContent
? - ASP.NET Web API 2 - StreamContent is extremely slow
This answer seems to describe the solution to my problem. AHttpRequestMessage
object is used to create aHttpResponseMessage
object. Then aStreamContent
object is assigned to theHttpResponseMessage.Content
. But where do I get aHttpRequestMessage
, and what should I change in my signatures to be able to return aHttpResponseMessage
?
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