我正在使用以下API,它们以Data
对象的Error
对象作为响应
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
,其中Data或Error都将其初始化为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; }
}
为了简单地解决问题,现在我一次只能处理1个ID。
使用ServiceStack Client使用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();
}
}
此问题未用ServiceStack标记,因为我愿意使用以下方法解决方案: HttpWebRequest / Response类, WebClient类, HttpClient类, RestSharp NuGet软件包, ServiceStack Http Utils,或任何使我的生活更轻松的事情。
我之所以使用ServiceStack,是因为documentation说我可以使用类似的东西:
client.GetAsync(new Hello { Name = "World!" })
.Success(r => r => r.Result.Print())
.Error(ex => { throw ex; });
使用Success
和Error
将单返回类型映射为我的Response
类型。
答案 0 :(得分:1)
如果您正在使用ServiceStack,则应按在文档中找到的方式使用它,但这意味着您实际上会在id不存在时实际抛出(自定义)异常。然后,您的自定义异常将包含代码和消息。因此,当您想返回错误时,您实际上只会抛出异常。
但是,我不认为这是您应该做的,因为只有在例外情况发生时才应使用异常,但据我所知,错误是经常发生的常见且正常的行为(例如客户)会尝试并使用ID出错)。因此,我建议使用HttpWebResponse类作为您的返回类型。在那里,您基本上可以设置HTTP返回状态(例如400、404)和json(或实际上任何)数据。
答案 1 :(得分:0)
ServiceStack C#/.NET Service Clients支持同步和异步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;
}
}
如果您的方法也是异步的,则应该仅使用异步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;
}
}