如何在Asp.Net中的Server.Transfer之前设置响应头?

4

我有一个页面,根据特定条件,我要么使用Response.Redirect,要么使用Server.Transfer。现在我想为这两种情况添加一个标题。所以我正在进行以下操作:

    Response.AddHeader("Vary", "User-Agent");

    if (condition) 
    {
        Server.Transfer(redirectUrl);
    }
    else
    {
        Response.Redirect(redirectUrl);
    }

现在,当代码通过Server.Transfer路径时,Vary标头设置为*,而当代码通过Response.Redirect路径时,标头正确设置为User-Agent。
为什么会发生这种情况,如何才能使两种情况下响应标头相同?
3个回答

6
当您调用Server.Transfer方法时,当前页面的Response对象将被目标页面的Response对象(实际发送给用户的Response对象)所取代。因此,如果您想要设置特定的Header属性,必须在目标页面上进行设置。
如果是有条件的话,您可以使用一个HttpContext.Items属性,在第一个页面上设置它并在第二个页面上读取。
祝好!

2
我认为在这种情况下HttpContext.Items可能比Session更合适。Session将在请求之间保留,而Items将在请求完成后清除。 - Dean Ward
@DeanWard 你说得对!随意编辑答案以改进它。 - Andre Calil

4

André说得对,Server.Transfer会替换响应对象。如果您希望被传输的页面不受父级影响,您可以将信息存储到HttpContext.Items中,然后使用IHttpModule提取信息并适当地配置标头。下面的代码可能会达到预期效果...

Items.Add(VaryHttpModule.Key, "User-Agent");

if (condition) 
{
    Server.Transfer(redirectUrl);
}
else
{
    Response.Redirect(redirectUrl);
}

public class VaryHttpModule : IHttpModule
{
    public const string Key = "Vary";

    public void Init(HttpApplication context)
    {
        context.PostRequestHandlerExecute +=
            (sender, args) =>
                {
                    HttpContext httpContext = ((HttpApplication)sender).Context;
                    IDictionary items = httpContext.Items;
                    if (!items.Contains(Key))
                    {
                        return;
                    }

                    object vary = items[Key];
                    if (vary == null)
                    {
                        return;
                    }

                    httpContext.Response.Headers.Add("Vary", vary.ToString());
                };
    }

    public void Dispose()
    {
    }
}

Cheers!


0
Source.aspx 中添加标题,不要更改 Destination.aspx 页面中的标题。
如果您想将结果页面显示为 HTML,则应添加标题 content-typetext/html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接