Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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# 如何用Web Api实现请求/响应模式?_C#_Asp.net Mvc 4_Asp.net Web Api - Fatal编程技术网

C# 如何用Web Api实现请求/响应模式?

C# 如何用Web Api实现请求/响应模式?,c#,asp.net-mvc-4,asp.net-web-api,C#,Asp.net Mvc 4,Asp.net Web Api,我是MVCWebAPI新手,但我有一些使用ServiceStack框架的经验。有些web api示例看起来很像RPC,具有更多的操作方法和更少的参数。事实上,大多数示例似乎都将request参数限制为id。我想使用request/response创建一些报告服务,因为请求与所有报告条件都非常复杂 以下是我简化的请求/响应类型: public class PendingRequest { public string Id { get; set; } public int Accou

我是MVCWebAPI新手,但我有一些使用ServiceStack框架的经验。有些web api示例看起来很像RPC,具有更多的操作方法和更少的参数。事实上,大多数示例似乎都将request参数限制为id。我想使用request/response创建一些报告服务,因为请求与所有报告条件都非常复杂

以下是我简化的请求/响应类型:

public class PendingRequest
{
    public string Id { get; set; }
    public int AccountId { get; set; }
    public DateTime? FromDate { get; set; }
    public DateTime? ToDate { get; set; }
}

public class PendingResponse
{
    public string Id { get; set; }
    public IEnumerable<Pending> Data { get; set; }
}
因此,通过这个路由,我打算将操作作为报告的名称。注意我没有在这里包括request参数。我不知道我该不该

问题实际上在客户端。对于HttpClient,GetAsync方法不允许包含JSON请求对象。我看到了一个扩展方法PostAsJsonAsync,但肯定这不应该是一个帖子?如果没有GetAsJsonAsync或类似的代码,那么我就看不到将请求包含在GET中的方法

老实说,我更喜欢ServiceStack,但似乎还没有异步支持。我需要开发一些I/O密集型的高性能服务,我希望尽可能减少阻塞

更新:

如果我将模型的参数作为查询字符串的一部分,而不是使用请求体,那么WebAPI似乎将执行模型绑定。为了实现这一点,Get方法需要在模型类型前面加上[FromUri]属性,这会通知模型绑定器应该从请求查询字符串构造模型。凌乱,但有效

[ActionName("Pending")]
public async Task<PendingResponse> GetPending([FromUri] PendingRequest request)
{
    return new PendingResponse
    {
        Id = request.Id,
        // query = ...build from request params
        // Data = await Repo.GetPending(query)
    };
}
[ActionName(“待定”)]
公共异步任务GetPending([FromUri]PendingRequest请求)
{
返回新的Pendingreponse
{
Id=request.Id,
//query=…从请求参数生成
//Data=wait Repo.GetPending(查询)
};
}
现在在客户端,我执行以下操作:

var result = await _httpClient.GetAsync("api/reports/pending?Id=123&AccountId=456");
result.EnsureSuccessStatusCode();
var response = await result.Content.ReadAsAsync<PendingResponse>();
var result=await\u httpClient.GetAsync(“api/reports/pending?Id=123&AccountId=456”);
result.EnsureSuccessStatusCode();
var response=wait result.Content.ReadAsAsync();

对服务的调用会导致调用GetPending方法,并从提供的查询字符串参数中获得PendingRequest对象的副本。

有点猜测,但是只对JSON请求对象进行URL编码并将其放入GET URI的查询字符串段怎么样


此外,您可能需要在操作中的请求方法参数上使用[FromUri]属性,因为它是一个复杂类型。我可能错过了一些东西,但是这篇文章没有提到GET是复杂类型的特例,因此我认为他们总是会尝试从文章正文中阅读

这里的基本问题是您试图为HTTP GET提供一个请求主体,这是不允许的。好的,您仍然可以继续使用请求正文格式化GET并提交它,但这并不符合规范。严格来说,HTTP规范并不禁止GET请求具有正文,但GET请求的响应不能根据请求正文而更改,这基本上意味着您不能在GET请求主体中使用搜索条件。您可以使用URI路径和查询字符串来指定搜索条件,如果要将它们绑定到复杂类型参数中,则需要像这样使用
[FromUri]
公共异步任务GetPending([FromUri]PendingRequest request)

这很有趣。如果语句“…但是GET请求的响应不能基于请求体更改”为真,那么我不能使用GET,因为对/api/reports/pending的请求即使没有任何条件,也可能随着时间的推移产生不同的结果。也许那时我们真的在谈论发表一篇文章。我应该把它看作是在创建报告(请求请求)或某事中的一种创作……随着时间的推移,响应与使用请求主体发送不同的响应完全不同。也许我不清楚。看看这个-,谢谢你,巴德里。最初的答案是正确的,我已经用一个示例客户电话更新了我的帖子。现在我只需要一个好的对象->查询字符串映射器。
[ActionName("Pending")]
public async Task<PendingResponse> GetPending([FromUri] PendingRequest request)
{
    return new PendingResponse
    {
        Id = request.Id,
        // query = ...build from request params
        // Data = await Repo.GetPending(query)
    };
}
var result = await _httpClient.GetAsync("api/reports/pending?Id=123&AccountId=456");
result.EnsureSuccessStatusCode();
var response = await result.Content.ReadAsAsync<PendingResponse>();