使用泛型对象创建响应

本文关键字:创建 响应 对象 泛型 | 更新日期: 2023-09-27 18:13:59

我试图找出一种方法来返回一个对象在我的响应,同时仍然保持一个可理解的返回类型。

对于初学者来说,我知道这是预期的。

public async Task<HttpResponseMessage> DoMyThing(MyObject myObject)
{
    var result = await _myService.CreateMyThingAsync(myObject);
    return Request.CreateResponse(HttpStatusCode.Created, result);
}

但是我真正想要的是这个伪代码的工作…。

public Task<MyObject> DoMyThing(MyObject myObject)
{
    var result = _myService.CreateMyThingAsync(myObject);
    return Request.CreateResponse<Task<MyObject>>(HttpStatusCode.Created, result);
    // or better yet
    return Request.CreateResponse<MyObject>(HttpStatusCode.Created, result);
}

框架中有什么神奇的东西可以让它发生吗?或者是否有第三方库可以做到这一点?

实际上我需要返回Task<MyObject>而不是Task<HttpResponseMessage>

我也愿意接受其他关于如何返回非200响应的建议,同时仍然返回Task<MyObject>

使用泛型对象创建响应

将类型指定为返回类型的问题是,您将自己限制为必须返回该类型。这听起来可能很奇怪,但实际上在很多情况下,您需要能够支持多个响应,例如404、200、201等等。

要处理此文档,您可以使用ResponseType属性,如下所示:

[ResponseType(typeof(BookDto))]
        public async Task<IHttpActionResult> GetBook(int id)
        {
            BookDto book = await db.Books.Include(b => b.Author)
                .Where(b => b.BookId == id)
                .Select(AsBookDto)
                .FirstOrDefaultAsync();
            if (book == null)
            {
                return NotFound();
            }
            return Ok(book);
        }

看这里

编辑:

在Asp。Net Core使用ProducesResponseType属性,该属性可以在每个方法中使用多次

看到

例子
[ProducesResponseType(typeof(BookDto), 200)]
[ProducesResponseType(typeof(object), 201)]
         public async Task<IActionResult> GetBook(int id)
            {
                BookDto book = await db.Books.Include(b => b.Author)
                    .Where(b => b.BookId == id)
                    .Select(AsBookDto)
                    .FirstOrDefaultAsync();
                if (book == null)
                {
                    return NotFound();
                }
                return Ok(book);
            }

编辑:多个响应属性先于点网核心

你可以使用Swagger来帮助文档/描述你的API,他们有一个自定义属性叫做SwaggerResponse

Swagger的。net端口是Swashbuckle,请看这里

这将是WebApi中最好的模式。

    public async Task<IHttpActionResult> DoMyThing(MyObject myObject)
    {
        try
        {                           
            var result = await _myService.CreateMyThingAsync(myObject);
            return new JsonStreamHttpActionResult<MyObject>(Request, System.Net.HttpStatusCode.Created, result);
        }
        catch (Exception ex)
        {
            Logger.Instance.Error(ex);
            return new HttpActionResult(HttpStatusCode.InternalServerError, "An error has occured");
        }
    }

与泛型序列化器。然后你可以使用"更好的"IHttpActionResult而不是真正的返回值。

public class JsonStreamHttpActionResult<T> : IHttpActionResult
{
    private T responseData;
    private HttpRequestMessage request;
    private HttpStatusCode statusCode;
    public JsonStreamHttpActionResult(HttpRequestMessage request, System.Net.HttpStatusCode code, T responseData)
    {
        this.responseData = responseData;
        this.request = request;
        this.statusCode = code;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = request.CreateResponse(statusCode);
        response.Content =
                new PushStreamContent((stream, content, context) =>
                {
                    var serializer = new Newtonsoft.Json.JsonSerializer();
                    using (var writer = new System.IO.StreamWriter(stream))
                    {
                        serializer.Serialize(writer, responseData);
                        stream.Flush();
                    }
                });
        return Task.FromResult(response);
    }
}