Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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/1/asp.net/31.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# 在ApiController中添加自定义响应标头_C#_Asp.net_Asp.net Web Api_Http Headers_Asp.net Web Api2 - Fatal编程技术网

C# 在ApiController中添加自定义响应标头

C# 在ApiController中添加自定义响应标头,c#,asp.net,asp.net-web-api,http-headers,asp.net-web-api2,C#,Asp.net,Asp.net Web Api,Http Headers,Asp.net Web Api2,到目前为止,我有一个GET方法,如下所示: protected override async Task<IHttpActionResult> GetAll(QueryData query) { // ... Some operations //LINQ Expression based on the query parameters Expression<Func<Entity, bool>> queryExpression =

到目前为止,我有一个
GET
方法,如下所示:

protected override async Task<IHttpActionResult> GetAll(QueryData query)
{
     // ... Some operations

     //LINQ Expression based on the query parameters
     Expression<Func<Entity, bool>> queryExpression = BuildQueryExpression(query);

     //Begin to count all the entities in the repository
     Task<int> countingEntities = repo.CountAsync(queryExpression);

     //Reads an entity that will be the page start
     Entity start = await repo.ReadAsync(query.Start);

     //Reads all the entities starting from the start entity
     IEnumerable<Entity> found = await repo.BrowseAllAsync(start, queryExpression);

     //Truncates to page size
     found = found.Take(query.Size);

     //Number of entities returned in response
     int count = found.Count();

     //Number of total entities (without pagination)
     int total = await countingEntities;

     return Ok(new {
          Total = total,
          Count = count,
          Last = count > 0 ? GetEntityKey(found.Last()) : default(Key),
          Data = found.Select(e => IsResourceOwner(e) ? MapToOwnerDTO(e) : MapToDTO(e)).ToList()
     });
}
protectedoverride异步任务GetAll(QueryData查询)
{
//…一些行动
//基于查询参数的LINQ表达式
表达式queryExpression=BuildQueryExpression(查询);
//开始计算存储库中的所有实体
任务计数属性=repo.CountAsync(queryExpression);
//读取将作为页面开始的实体
实体start=wait repo.ReadAsync(query.start);
//读取从起始实体开始的所有实体
IEnumerable found=wait repo.browsellasync(start,queryExpression);
//截断到页面大小
found=found.Take(query.Size);
//响应中返回的实体数
int count=found.count();
//实体总数(不分页)
int total=等待计数;
返回Ok(新的{
总计=总计,
计数=计数,
Last=count>0?GetEntityKey(find.Last()):默认值(Key),
Data=found.Select(e=>IsResourceOwner(e)?MapToOwnerDTO(e):maptoodto(e)).ToList()
});
}
这很有魅力,很好。但是,我最近被告知将响应元数据(即,
总计
计数
最后一次
属性)作为响应自定义头而不是响应正文发送

我无法从ApiController访问
响应
。我想到了一个过滤器或属性,但如何获取元数据值呢

我可以在响应中保留所有这些信息,然后使用一个过滤器,在将响应发送到客户端之前对其进行反序列化,并使用头创建一个新的响应,但这看起来既麻烦又糟糕


是否有一种方法可以直接从ApiController上的此方法添加自定义标题?

您可以使用自定义操作筛选器,该筛选器将允许您发送自定义标题并访问HttpContext:

public class AddCustomHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       actionExecutedContext.Response.Content.Headers.Add("name", "value");
    }
}

我已经输入了评论,这是我的完整答案

您需要创建一个自定义过滤器并将其应用于控制器

public class CustomHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       var count = actionExecutedContext.Request.Properties["Count"];
       actionExecutedContext.Response.Content.Headers.Add("totalHeader", count);
    }
}
在控制器中

  public class AddressController : ApiController
        {
            public async Task<Address> Get()
            {
               Request.Properties["Count"] = "123";
            }
    }
公共类地址控制器:ApiController
{
公共异步任务Get()
{
请求属性[“计数”]=“123”;
}
}

您可以在如下方法中显式添加自定义标题:

[HttpGet]
[Route("home/students")]
public HttpResponseMessage GetStudents()
{
       // Get students from Database

       // Create the response
        var response = Request.CreateResponse(HttpStatusCode.OK, students);
    
        // Set headers for paging
        response.Headers.Add("X-Students-Total-Count", students.Count());
       
       return response;
}
有关更多信息,请阅读本文:

您需要的是:

public async Task<IHttpActionResult> Get() 
{ 
    var response = Request.CreateResponse();
    response.Headers.Add("Lorem", "ipsum");

    return base.ResponseMessage(response); 
}
公共异步任务Get() { var response=Request.CreateResponse(); 添加(“Lorem”、“ipsum”); 返回base.ResponseMessage(响应); }
我希望这能回答你的问题

简单的解决方案就是这样写:

HttpContext.Current.Response.Headers.Add("MaxRecords", "1000");

或者,如果您需要在每个响应上执行DelegatingHandler,那么最好利用DelegatingHandler。因为它将在请求/响应管道上工作,而不是在控制器/操作级别。在我的例子中,我必须为每个响应添加一些标题,所以我做了我所描述的。请参阅下面的代码片段

public class Interceptor : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);
        response.Headers.Add("Access-Control-Allow-Origin", "*");
        response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,PUT,OPTIONS");
        response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token, content-type");
        return response;
    }

}


应该像@Andrei一样简单我没有
HttpContext
属性,但是我有一个
ActionContext
属性。但是,该对象的
Response
属性为
null
,我无法对其进行操作。您需要使用ActionContext.Request.CreateSponse()实际创建响应,然后将响应中的值设置为强类型对象,而不是strings@entre我想让Web Api序列化我的匿名对象(即,使用Web Api
Ok(T)
方法。这还包括为我设置一些标题)。如果我创建响应,我必须序列化我的对象,并手动设置所有标题。移动方法中的所有标题设置部分,并在两个位置使用该方法,但我如何获得“值”标题?有趣的问题。看起来您可以在控制器中设置属性Request.Properties[“Count”]=“123”,并在筛选器中使用它。在筛选器中,您可以通过actionContext.Request.Properties[“Count”]访问它这很好地工作,但这是正确的方法吗?我的元数据应该是响应的属性,而不是请求的属性。我的意思是,它可以作为一个解决方案工作,但在概念上正确吗?对我来说,这看起来像是双重工作。你可以添加一个头@Nikola,但随后你会丢失强类型响应,OP没有使用它,但它仍然是一个选项这种方法。我正在处理一个web api项目,不使用强类型会导致问题——其中一个问题是我们无法轻松生成正确的招摇过市。如果您可以,请避免返回非类型的响应。在我的情况下,我发现这是在标题中返回响应数据的最佳解决方案,但您必须小心操作筛选器获取数据的位置。我必须为您正在处理的请求获取数据,我到处寻找请求特有的数据存储,唯一能找到的是“context.request.Properties”表,这很可能是@Yousuf使用它的原因。请记住,在处理操作时,“context.Response”对象不存在,所以“context.Request"似乎是唯一可以存储数据的地方。对于强类型的响应,不幸的是HTTP协议的性质,所有数据都是文本。您可以考虑一些XML或JSON格式,包括键入以验证数据的传输。我这样做,但标题得到。stripped@weagle08您的请求是否通过代理s?如果是这样,您可以阅读以下内容:为我工作,但我们的ConnectionTanks Darek中没有涉及代理,用于代码突出显示。我将确保从现在开始执行此操作:)HttpContext不会出现在派生ApicController的控制器中。如果我们讨论的是从
system.web.http.ApicController
派生的.net framework控制器,那么这确实是正确的答案。我个人只熟悉核心语法,所以
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MessageHandlers.Add(new Interceptor());
        }
    }