WebApi2 IHttpActionResult强类型返回值 [英] WebApi2 IHttpActionResult strongly typed return values

查看:257
本文介绍了WebApi2 IHttpActionResult强类型返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这是一个非常简单的例子!)

  [可序列化] 
public class MyRecord
{
public string key {get; set;}
public string data {get; set;}
}

public async Task< IHttpActionResult> Get(string SomeKey)
{
if(ExistsInDB(SomeKey))
{
return Ok(SomeRecordFromDB(SomeKey)); // SomeRecord()返回一个POCO MyRecord。
}
else
{
//我知道我可以返回NotFound(),但不是我Q
的焦点返回Ok(false); //返回False
}
}

有效地展示没有编译时间错误检查返回类型。这个例子将返回一个JSon序列化的POCO类(JSon被设置在我的accept头上),或者它将返回文本False,这会将类型检查的负担放在客户端上。



我不会按设计做这件事,但我的团队正在重构asmx / svc中的很多代码,并且出现错误。我喜欢当编译器有助于捕获这些类型的错误而不是等待模块或单元测试时。



返回使用强类型方法签名的正确方法(避免IHttpActionResult和Ok(),NotFound()等帮助程序,还是有类似于 IHttpActionResult< T> ,可以用来确保返回正确的类型?



M。

解决方案

首先,它是一个好的做法是返回 IHttpActionResult ,表示相应的 http状态,例如:

  public async Task< IHttpActionResult> Get(string SomeKey)
{
if(ExistsInDB(SomeKey))
return Ok(SomeRecordFromDB (SomeKey));

return NotFound();
}

但是,如果您确实想要一个强类型的api,您可以执行如下操作:

  public async Task< StronglyTypeResponse> Get()
{
返回新的StronglyTypeResponse();
}

或者,创建一个类型化的响应,并保持http状态码,等在您的回应:

  public class StronglyTypeResponse 
{

}

public class StronglyTypedResult< T> :IHttpActionResult
{
HttpConfiguration _configuration;
T _content;
HttpStatusCode _statusCode;
HttpRequestMessage _request;

public StronglyTypedResult(T内容,HttpStatusCode statusCode,HttpRequestMessage请求,HttpConfiguration配置)
{
_content = content;
_request = request;
_configuration = configuration;
_statusCode = statusCode;
}

public Task< HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(_statusCode)
{
Content = new ObjectContent< dynamic>(_ content,_configuration.Formatters.JsonFormatter),
RequestMessage = _request,
ReasonPhrase =某个短语
};

返回Task.FromResult(response);


然后你可以创建你的方法:

  public async Task< StronglyTypedResult< StronglyTypeResponse>> Get()
{
返回新的StronglyTypedResult< StronglyTypeResponse>(新的StronglyTypeResponse(),HttpStatusCode.OK,Request,Configuration);

$ / code $ / $ p

创建自定义泛型IHttpActionResult



基本上是一样的:

  public class IHttpActionResult< T> :System.Web.Http.IHttpActionResult 
{
HttpConfiguration _configuration;
T _content;
HttpStatusCode _statusCode;
HttpRequestMessage _request;

public IHttpActionResult(T内容,HttpStatusCode statusCode,HttpRequestMessage请求,HttpConfiguration配置)
{
_content = content;
_request = request;
_configuration = configuration;
_statusCode = statusCode;
}

public Task< HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(_statusCode)
{
Content = new ObjectContent< dynamic>(_ content,_configuration.Formatters.JsonFormatter),
RequestMessage = _request,
ReasonPhrase =某个短语
};

返回Task.FromResult(response);


$ / code $ / pre

现在你可以返回你想要的类键入 IHttpActionResult

  public async Task< IHttpActionResult< YourClass>> Get()
{
var yourclass = new YourClass();

返回新的IHttpActionResult< YourClass>(yourclass,HttpStatusCode.OK,Request,Configuration);
}


It is possible and not ideal to do this: (a vastly simplified example!)

[Serializable]
public class MyRecord
{
    public string key {get; set;}
    public string data {get; set;}
}

public async Task<IHttpActionResult> Get(string SomeKey)
{
    if(ExistsInDB(SomeKey))
    {
        return Ok(SomeRecordFromDB(SomeKey));  //SomeRecord() returns a POCO MyRecord.
    }
    else
    {
        //I know I can return NotFound() but not the focus of my Q
        return Ok(false);  //returns "False"
    }
}

Effectively demonstrating no compile time error checking on the return type. This example will return either a JSon serialized POCO class (JSon is set on my accept header) or it will return the text "False" which puts the burden of type checking on the client.

I wouldn't do this by design but my team is refactoring a lot of code from asmx/svc and mistakes creep in. I like it when the compiler helps to trap these kinds of errors rather than waiting for module or unit testing.

Is the right way to go back to using strongly typed method signatures (avoiding the IHttpActionResult and the Ok(), NotFound(), etc helpers or is there something like a IHttpActionResult<T> that can be used to make sure the right type is being returned?

M.

解决方案

First of all, it is a good practice to return IHttpActionResult, indicating the corresponding http status. Something like:

public async Task<IHttpActionResult> Get(string SomeKey)
{
    if(ExistsInDB(SomeKey))
        return Ok(SomeRecordFromDB(SomeKey));

    return NotFound();
}

But if you really want to have a strongly typed api, you can do something like:

 public async Task<StronglyTypeResponse> Get()
 {
     return new StronglyTypeResponse();
 }

Or, create a typed response, and you'll keep the http status code, etc in your response:

public class StronglyTypeResponse
{

}

public class StronglyTypedResult<T> : IHttpActionResult
{
    HttpConfiguration _configuration;
    T _content;
    HttpStatusCode _statusCode;
    HttpRequestMessage _request;

    public StronglyTypedResult(T content, HttpStatusCode statusCode, HttpRequestMessage request, HttpConfiguration configuration)
    {
        _content = content;
        _request = request;
        _configuration = configuration;
        _statusCode = statusCode;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(_statusCode)
        {
            Content = new ObjectContent<dynamic>(_content, _configuration.Formatters.JsonFormatter),
            RequestMessage = _request,
            ReasonPhrase = "some phrase"
        };

        return Task.FromResult(response);
    }
}

And then you can create your method:

public async Task<StronglyTypedResult<StronglyTypeResponse>> Get()
{
    return new StronglyTypedResult<StronglyTypeResponse>(new StronglyTypeResponse(), HttpStatusCode.OK, Request, Configuration);
}

Creating your own custom generic IHttpActionResult

It's basically the same:

public class IHttpActionResult<T> : System.Web.Http.IHttpActionResult
{
    HttpConfiguration _configuration;
    T _content;
    HttpStatusCode _statusCode;
    HttpRequestMessage _request;

    public IHttpActionResult(T content, HttpStatusCode statusCode, HttpRequestMessage request, HttpConfiguration configuration)
    {
        _content = content;
        _request = request;
        _configuration = configuration;
        _statusCode = statusCode;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(_statusCode)
        {
            Content = new ObjectContent<dynamic>(_content, _configuration.Formatters.JsonFormatter),
            RequestMessage = _request,
            ReasonPhrase = "some phrase"
        };

        return Task.FromResult(response);
    }
}

And now you can return the class you want with a typed IHttpActionResult:

public async Task<IHttpActionResult<YourClass>> Get()
{
    var yourclass = new YourClass();

    return new IHttpActionResult<YourClass>(yourclass, HttpStatusCode.OK, Request, Configuration);
}

这篇关于WebApi2 IHttpActionResult强类型返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆