Se você herda da base NegotitatedContentResult<T>, como mencionado, e não precisa transformar o seu content(por exemplo, você quer apenas retornar uma string), não precisa sobrescrever o ExecuteAsyncmétodo.
Tudo o que você precisa fazer é fornecer uma definição de tipo apropriada e um construtor que diga à base qual código de status HTTP retornar. Todo o resto simplesmente funciona.
Aqui estão alguns exemplos para NotFounde InternalServerError:
public class NotFoundNegotiatedContentResult : NegotiatedContentResult<string>
{
public NotFoundNegotiatedContentResult(string content, ApiController controller)
: base(HttpStatusCode.NotFound, content, controller) { }
}
public class InternalServerErrorNegotiatedContentResult : NegotiatedContentResult<string>
{
public InternalServerErrorNegotiatedContentResult(string content, ApiController controller)
: base(HttpStatusCode.InternalServerError, content, controller) { }
}
E então você pode criar métodos de extensão correspondentes para ApiController(ou fazer isso em uma classe base se você tiver uma):
public static NotFoundNegotiatedContentResult NotFound(this ApiController controller, string message)
{
return new NotFoundNegotiatedContentResult(message, controller);
}
public static InternalServerErrorNegotiatedContentResult InternalServerError(this ApiController controller, string message)
{
return new InternalServerErrorNegotiatedContentResult(message, controller);
}
E então eles funcionam exatamente como os métodos integrados. Você pode chamar o existente NotFound()ou pode chamar o seu novo personalizado NotFound(myErrorMessage).
E, claro, você pode se livrar dos tipos de string "embutidos no código" nas definições de tipo personalizado e deixá-los genéricos se quiser, mas então você pode ter que se preocupar com as ExecuteAsynccoisas, dependendo do que você <T>realmente é.
Você pode examinar o código-fonte para NegotiatedContentResult<T>ver tudo o que ele faz. Não há muito a fazer.