Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 来自API的多个返回类型 输入和API定义:_C#_Rest - Fatal编程技术网

C# 来自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": { } }, {

我正在使用下面的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": { }
}, {
  "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
将单个返回类型映射到my
Response
类型

如果您使用的是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;
    }
}