HttpResponseMessage为内容类型image / jpeg调用了两次

时间:2013-05-16 08:09:46

标签: c# asp.net-web-api

我的机器在MS WebAPI(.net4)上托管RESTful服务,并且还连接到摄像头。我可以请求让相机拍摄快照(jpg)并显示拍摄的图像。 奇怪的是,请求总是被称为2x - 捕获2个图像,但只返回最后一个图像作为输出。 (使用谷歌铬邮差测试)

在我的服务器中:

var config = new HttpSelfHostConfiguration(string.Format("http://localhost:{0}/", port));
config.MessageHandlers.Add(new SimpleFileHandler());
config.Formatters.Add(new JpegTypeFormatter());
config.Routes.MapHttpRoute( /* the route map */
SimpleFileHandler中的

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    return base.SendAsync(request, cancellationToken);
}

一个名为JpegMediaFormatter的jpeg内容类型格式化程序:

public class JpegTypeFormatter : MediaTypeFormatter
{
    private static Type _supportedType = typeof(MemoryStream);

public JpegTypeFormatter()
{
    SupportedMediaTypes.Add(new MediaTypeHeaderValue(MediaTypeNames.Image.Jpeg));
}

public override bool CanReadType(Type type)
{
    return type == _supportedType;
}

public override bool CanWriteType(Type type)
{
    return type == _supportedType;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
    throw new NotImplementedException();
}

private Task GetWriteTask(Stream stream, MemoryStream data)
{
    return new Task(() =>
        {
            var ms = new MemoryStream(data.ToArray());
            ms.CopyTo(stream);
        });
}

public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
    if (value == null)
    {
        //value = new byte[0];
        value = new MemoryStream();
    }
    Task writeTask = GetWriteTask(writeStream, (MemoryStream)value);
    writeTask.Start();
    return writeTask;
}

}

相机捕捉RESTful通话:

[HttpGet]
public HttpResponseMessage Capture(int width)
{ // call camera API, capture image and save as img
    var memoryStream = new MemoryStream();
    img.Save(memoryStream, ImageFormat.Jpeg);
    return Request.CreateResponse(HttpStatusCode.OK, memoryStream, 
        new MediaTypeHeaderValue(MediaTypeNames.Image.Jpeg));
}

以某种方式调用带有JPEG内容的新MediaTypeHeaderValue()将导致GET被调用两次。 如果我改为调用其他MediaType,即application / json,则GET不会被称为2x。

为什么会发生这种情况?

编辑:其他详细信息 服务器代码:

public Server : IDisposable
{
    HttpSelfHostServer _server;
    public Server()
    {
        var config = new HttpSelfHostConfiguration("http://localhost:30019");
        config.Routes.MapHttpRoute("capture", "camera/capture/");
        _server = new HttpSelfHostServer(config);
        _server.OpenAsync().Wait();
    }
...
}

相机控制器:

public class CameraController : ApiController
{
    // camera -> variable to camera h/w
    var camera = HW.Camera;
    var img = camera.Capture();
    if(img != null)
    {
        var memoryStream = new MemoryStream();
        img.Save(memoryStream, ImageFormat.Jpeg);
        var resp = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK;
            Content = new PushStreamContent((respStream, cnt, ctx) =>
            {
                using(respStream)
                {
                    memoryStream.WriteTo(respStream);
                }
            });
        };
        resp.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
        return resp;
    }
}

1 个答案:

答案 0 :(得分:0)

我想了解你的要求......'img'是什么类型的?而且我认为您可以避免创建自定义格式化程序。例如:

    [HttpGet]
    public HttpResponseMessage Capture(int width)
    { 
        HttpResponseMessage response = new HttpResponseMessage();
        response.Content = new PushStreamContent((responseStream, httpContent, transportContext) =>
            {
                using (responseStream)
                {
                    img.Save(responseStream, ImageFormat.Jpeg);

                }//closing this important!
            });
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");

        return response;
    }

如果您已将图像作为文件,则可以执行以下操作以回复图像:

[HttpGet]
    public HttpResponseMessage Capture(int width)
    { 
        HttpResponseMessage response = new HttpResponseMessage();
        response.Content = new StreamContent(File.OpenRead(@"C:\Images\Car.jpg"));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");

        return response;
    }