如何从控制器返回通用响应? [英] How to return Generic response from Controller?

查看:106
本文介绍了如何从控制器返回通用响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Net核心应用程序,并调用其他.Net Core Web API应用程序.我正在按如下方式调用控制器方法

Net core application and calling other .Net Core Web API application. I am calling controller methods as below

public async Task<T> SendRequest<T, U>(U request, string methodName, HttpMethod reqtype, string token)
        {
            T res = default(T);
            try
            {
                string url = methodName;
                string contentJson = JsonConvert.SerializeObject(request);
                var content = new StringContent(contentJson, Encoding.UTF8, "application/json");
                var actualRequest = new HttpRequestMessage(reqtype, url);
                actualRequest.Content = content;
                _httpClient.DefaultRequestHeaders.Clear();
                _httpClient.DefaultRequestHeaders.Add("Authorization", token);
                var rawData = await _httpClient.SendAsync(actualRequest);
                var processedData = await rawData.Content.ReadAsStringAsync().ConfigureAwait(false);
                res = JsonConvert.DeserializeObject<T>(processedData);
            }
            catch (Exception ex)
            {
                _reqHandler.RaiseBusinessException(MethodBase.GetCurrentMethod()?.DeclaringType?.DeclaringType?.Name
                    , MethodBase.GetCurrentMethod().Name,
                    "InputType: " + typeof(U) + " || OutputType: " + typeof(T) + " || Error Message: " + ex.Message);
            }
            return res;
        }  

下面是从API控制器返回的示例

Below are the samples returning from API controller

return StatusCode(404, result.MapFileFileUploadSummary);
 return StatusCode((int)System.Net.HttpStatusCode.Unauthorized);

在上面的代码中,当我返回一些状态代码时,我想将其绑定到通用类型T.例如,我正在调用一个方法

In the above code when I return some status code I want to bind it to genric type T. For example I am calling one method

 _Client.SendRequest<ObjectResult, requestModel>()

我正在将类型的ObjectResult发送为返回类型.例如,我在处理数据中低于响应,

I am sending ObjectResult of type as return type. I am getting below response in processedData for example,

"{\"type\":\"https://tools.ietf.org/html/rfc7235#section-3.1\",\"title\":\"Unauthorized\",\"status\":401,\"traceId\":\"00-e517f28f9c0b0441a8634c1c703a1cae-f64589d11056ad45-00\"}"

但无法将其绑定到

res = JsonConvert.DeserializeObject< T>(processedData); 这什么也没有返回,我要在此处添加屏幕截图

res = JsonConvert.DeserializeObject<T>(processedData); This returns nothing I am adding screenshot here

这里T的类型为ObjectResult.我在这里寻找通用响应类型,以便始终可以将其绑定到类型T.有人可以帮助我实现这一实现.任何帮助,将不胜感激.谢谢

here T is of type ObjectResult. I am looking for generic response type here so that I can always bind it to type T. Can some one help me with this implementation. Any help would be appreciated. Thank you

推荐答案

您遇到的问题是:如果出错,则JSON与成功将完全不同.

The issue you have is: In case of error the JSON will be totally different than if it succeed.

为示例起见,我将隐藏有关HTTP请求的大部分内容:

For the sake of example I will hide most part about the HTTP request :

public async Task<ActionResult<T>> SendRequest<T, U>(U request, string methodName, HttpMethod reqtype, string token);

对我来说,您不应返回"T"但是"ActionResult< T".您的代码仍然不知道实际的内容(T)​​,但知道它将返回ActionResult.它将减轻其余的负担.

For me you should not return "T" but "ActionResult<T>". Your code still doesn't know what will be the actual content (T) but know it will return the ActionResult. It will ease the rest.

var response = await _httpClient.SendAsync(actualRequest);
if (!response.IsSuccessStatusCode) 
{
   return new StatusCodeResult((int)response.StatusCode)
}
var responseData = JsonConvert.DeserializeObject<T>(await rawData.Content.ReadAsStringAsync());
return new ObjectResult(responseData);

在所有情况下,您都有一个ActionResult,可以直接从您的控制器返回它.

In all cases you will have an ActionResult that can be directly return from your controller.

如果发生错误,结果将仅是另一台服务器返回的状态代码.

In case of error the result will only be the status code returned by the other server.

如果成功,您将由另一台服务器发送数据.

In case of success you'll have the data send by the other server.

我认为在发生错误的情况下,将状态代码返回给用户就足够了,但是如果要发送整个对象,您也可以这样做.您只需要首先创建一个类,该类将代表发生错误时发送的数据,然后:

I think in case of error returning the status code to your user is enough but if to want to send the whole object you also can do it. You just need to create first a class that will represent the data sent in case of error then:

var response = await _httpClient.SendAsync(actualRequest);

object responseData;

if (response.IsSuccessStatusCode) 
{
    responseData = JsonConvert.DeserializeObject<T>(await rawData.Content.ReadAsStringAsync());
}
else 
{
   responseData = JsonConvert.DeserializeObject<YourClassInCaseOfError>(await rawData.Content.ReadAsStringAsync());
}

return new ObjectResult(responseData) 
{
   StatusCode = (int)response.StatusCode,  
}

您还必须将方法签名更改为:

And you also have to change the method signature to :

public async Task<ActionResult> SendRequest<T, U>(U request, string methodName, HttpMethod reqtype, string token);

由于第二个示例可能会返回2种不同的类型(数据类型或错误类型),因此您必须使用ActionResult,而不是ActionResult<>

Since the second example will potentially return 2 differents types (the data type or the error type) you have to use the ActionResult, not the ActionResult<>

这篇关于如何从控制器返回通用响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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