C# 来自API的多个返回类型 输入和API定义:
我正在使用下面的API,它用C# 来自API的多个返回类型 输入和API定义:,c#,rest,C#,Rest,我正在使用下面的API,它用错误对象的数据对象进行响应 FooBar方法:Ids是由逗号分隔的字符串列表 GET: /FooBar/v1{?ids} GET: /FooBar/v1/{ids} 请求标头: X-FooBar-Key: ## My key ## 答复:200 // if there is multiple IDs, response is an array of Data and Error [{ "data": { } }, { "data": { } }, {
错误对象的数据对象进行响应
FooBar方法:Ids是由逗号分隔的字符串列表
GET: /FooBar/v1{?ids}
GET: /FooBar/v1/{ids}
请求标头:
X-FooBar-Key: ## My key ##
答复:200
// if there is multiple IDs, response is an array of Data and Error
[{
"data": { }
}, {
"data": { }
}, {
"error": { }
}]
//If there is only one ID, response is the content of the data object
{
"code": "",
"date": "",
"status": "",
"message": "",
"link": "",
"type": ""
}
响应:400/404/etc,返回错误对象的内容
{
"code": "",
"message": ""
}
产出和预期成果:
我希望能够检查[1,N]ID,并且只有一个对象返回类型Response
,其中一个数据或错误初始化为null,另一个为null
public class Response
{
[JsonProperty("data")]
public Data Data { get; set; }
[JsonProperty("error")]
public Error Error { get; set; }
public string Id{ get; set; }
}
public class Error
{
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("code")]
[JsonConverter(typeof(StringEnumConverter))]
public ErrorCode Code { get; set; }
}
public class Data
{
[JsonProperty("status")]
[JsonConverter(typeof(StringEnumConverter))]
public Status Status { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("date")]
public string Date { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("link")]
public string Link { get; set; }
}
尝试:
为了解决目前的问题,我一次只处理一个Id。
使用ServiceStack客户端使用REST API
public class FooBarAPI : IFooBarAPI
{
Dictionary<string, string> DefaultHeader;
string BasePath; // https://foofoo.bar/FooBar/v1
public FooBarAPI(Dictionary<string, string> defaultHeader, string basePath)
{
DefaultHeader = defaultHeader;
BasePath = basePath;
}
public Response GetFooBar(string id)
{
JsonServiceClient client = new JsonServiceClient(BasePath);
client.RequestFilter = httpReq => httpReq.Headers.Add("X-FooBar-Key", DefaultHeader["X-FooBar-Key"]);
var response =
client.GetAsync<Response>($"/{id}"); // Null as for one ID the result is type Data not Response
// client.GetAsync<Data>($"/{id}"); // Working If not Error
var toto = response.Result;
toto.Id = id;
return toto;
}
public Response[] GetFooBar(string[] ids)
{ //
throw new NotImplementedException();
}
}
使用Success
和Error
将单个返回类型映射到myResponse
类型 如果您使用的是ServiceStack,那么您应该按照在文档中找到的方式使用它,但这意味着您实际上会在id不存在时抛出(自定义)异常。然后,自定义异常将包括代码和消息。所以当你想要返回一个错误时,你实际上只是抛出一个异常
但是,我不认为这是您应该做的,因为只有在异常情况发生时才应该使用异常,但据我所知,错误是经常发生的常见和正常行为(就像客户端尝试使用ID出错一样)。因此,我建议使用HttpWebResponse类作为返回类型。在那里,您基本上可以设置HTTP返回状态(例如400、404)和json(或实际上任何)数据 ServiceStack同时支持同步和异步API,因为您的方法是同步的,所以您应该只使用同步API,例如:
public Response GetFooBar(string id)
{
var client = new JsonServiceClient(BasePath) {
RequestFilter = req => req.Headers.Add(
"X-FooBar-Key", DefaultHeader["X-FooBar-Key"])
}
try
{
var response = client.Get<Response>($"/{id}");
response.Id = id; // Why isn't this already in the response?
return response;
}
catch (WebServiceException ex)
{
//Error Details
//ex.StatusCode;
//ex.ErrorCode;
//ex.ErrorMessage;
}
}
公共响应GetFooBar(字符串id)
{
var client=new JsonServiceClient(BasePath){
RequestFilter=req=>req.Headers.Add(
“X-FooBar-Key”,默认标题[“X-FooBar-Key”])
}
尝试
{
var response=client.Get($“/{id}”);
response.Id=Id;//为什么响应中没有这个?
返回响应;
}
捕获(WebServiceException ex)
{
//错误详细信息
//例如,状态代码;
//例如,错误代码;
//例如错误信息;
}
}
如果您的方法也是异步的,则只应使用异步API,例如:
public async Task<Response> GetFooBar(string id)
{
var client = new JsonServiceClient(BasePath) {
RequestFilter = req => req.Headers.Add(
"X-FooBar-Key", DefaultHeader["X-FooBar-Key"])
}
try
{
var response = await client.GetAsync<Response>($"/{id}");
response.Id = id; // Why isn't this already in the response?
return response;
}
catch (WebServiceException ex)
{
//Error Details
//ex.StatusCode;
//ex.ErrorCode;
//ex.ErrorMessage;
}
}
公共异步任务GetFooBar(字符串id)
{
var client=new JsonServiceClient(BasePath){
RequestFilter=req=>req.Headers.Add(
“X-FooBar-Key”,默认标题[“X-FooBar-Key”])
}
尝试
{
var response=await client.GetAsync($“/{id}”);
response.Id=Id;//为什么响应中没有这个?
返回响应;
}
捕获(WebServiceException ex)
{
//错误详细信息
//例如,状态代码;
//例如,错误代码;
//例如错误信息;
}
}
API代码是你写的吗?@ChetanRanpariya,不是。但是这个项目的负责人写了一篇关于设计API的白皮书。我会向高迪转达任何批评意见。并没有严格的规定,错误和回应不能以不同方式返回。实际上,当返回错误时,HttpResponseCode将不是200。因此,在尝试反序列化响应内容之前,客户端需要检查响应中的HttpResponseCode。如果API是同一产品、团队、部门、公司的一部分,那么可以讨论并实现它,以返回包装器对象,而不是不同的对象。但这完全取决于代码的所有者。作为一个API客户机,在API改变它的响应之前,你没有任何办法在同一个类中获得响应。当请求ID列表时,如果其中一个有效,响应是200。“对你来说,这是一个例外,对我来说,这是另一个星期四。”-M.Bison。该服务将发送一个404 not found(找不到任何早于1 mounth的内容)。不是我的设计。对于ID{valid,valid,invalid}的列表,我会得到一个200。在itI中,响应数组将有多种类型。我肯定会使用HttpWebResponse,它为您提供了更大的灵活性,因为您可以精确地定义在每种情况下要返回的响应。
public async Task<Response> GetFooBar(string id)
{
var client = new JsonServiceClient(BasePath) {
RequestFilter = req => req.Headers.Add(
"X-FooBar-Key", DefaultHeader["X-FooBar-Key"])
}
try
{
var response = await client.GetAsync<Response>($"/{id}");
response.Id = id; // Why isn't this already in the response?
return response;
}
catch (WebServiceException ex)
{
//Error Details
//ex.StatusCode;
//ex.ErrorCode;
//ex.ErrorMessage;
}
}