C#从函数中返回不同的类型

时间:2017-03-25 11:16:59

标签: c# asp.net json asp.net-mvc asp.net-mvc-5

我编写了以下代码,它基本上对我的服务器执行JSON请求:

   var client = new RestClient("mysite.com");
            var request = new RestRequest(Method.POST);
            request.RequestFormat = DataFormat.Json;
            request.AddParameter("application/x-www-form-urlencoded", /*params here...*/ ,ParameterType.RequestBody);
            return JsonConvert.DeserializeObject<MyCustomType>(client.Execute(request).Content);

请注意最后一行代码:

return JsonConvert.DeserializeObject<MyCustomType>(client.Execute(request).Content);

我将返回的JSON从服务器反序列化为我的应用程序中以前的类结构。

现在的问题是服务器可以返回错误响应或成功响应,对于每种情况,我需要一个不同的类结构,以便我可以将它们映射到C#类对象...

所以我觉得这样的事情可以做到:

public object PerformMyAwesomeRequest(string myToken) 
{
 var response =client.Execute(request).Content;
 var statusCode = FetchStatusCode(response);
if(statusCode == 0)//signaling the response returned error
{
return JsonConvert.DeserializeObject<ErrorMessageCustomType>(response);
}
else{
return JsonConvert.DeserializeObject<MyCustomType>(response);
}
}

所以这样它并没有给我任何错误......但是这里的问题是这些对象现在只存在于运行时,我无法确定我的.NET MVC Action中返回的类型服务器看起来像这样:

public ActionResult SomeActon(){
var response = PerformMyAwesomeRequest("mytokenhere...");
//response object is assigned a corresponding type only at runtime...
}

所以我的问题是:

  • 我可以从执行http请求的函数返回哪种类型的服务器,以便我可以直接在代码中知道函数返回的类型,而不仅仅是在运行时?

1 个答案:

答案 0 :(得分:8)

方法返回不同类型对象的唯一方法是返回它们的公共基类型。但是,您已经发现object的常见超类对您没有帮助,所以让我们考虑首先返回对象的替代方法:

  • 成功返回并抛出错误 - 此方法允许您返回MyCustomType,并抛出一些异常包装ErrorMessageCustomType。由于返回了一个对象,而另一个对象被抛出,因此不需要关联类型。
  • 返回合并对象 - 使用您计划返回的每种类型的成员创建类,并在PerformMyAwesomeRequest方法中仅设置其中一个。这不是很好,因为它需要调用者中的if - else链。
  • 接受错误的out参数 - 如果请求不成功,请返回null,并将out参数设置为ErrorMessageCustomType
  • 接受回调代理 - 而不是返回值,接受两个代理,一个代表成功,一个代表失败方案,即void PerformMyAwesomeRequest(string tok, Action<MyCustomType> onSuccess, Action<ErrorMessageCustomType> onError)

最后一种方法可以像这样使用:

PerformMyAwesomeRequest(
    myToken
,   data => {
        Console.WriteLine("Received data: {0}", data);
    }
,   error => {
        Console.WriteLine("Received error: {0}", error);
    }
);

该方法可以像这样实现:

public void PerformMyAwesomeRequest(string myToken, Action<MyCustomType> onSuccess, Action<ErrorMessageCustomType> onError) {
    var response = client.Execute(request).Content;
    var statusCode = FetchStatusCode(response);
    if (statusCode != 0) {
        onSuccess(JsonConvert.DeserializeObject<MyCustomType>(response));
    } else {
        onError(JsonConvert.DeserializeObject<ErrorMessageCustomType>(response));
    }
}