Silverlight 不支持 HttpWebRequest 上的标头

Posted

技术标签:

【中文标题】Silverlight 不支持 HttpWebRequest 上的标头【英文标题】:header on HttpWebRequest is not supported in Silverlight 【发布时间】:2016-06-07 01:33:59 【问题描述】:

我正在处理一个要求,我必须将自定义标头添加到 Silverlight 应用程序中的所有 HTTP 发布请求到在 IIS 中运行的 WCF 服务。

我实现了 IClientMessageInspector 和 IEndpointBehavior,并以编程方式将行为添加到客户端代理。我按照此处发布的说明进行操作: http://blogs.msmvps.com/paulomorgado/2007/04/26/wcf-building-an-http-user-agent-message-inspector/ http://adilmughal.com/blog/2011/10/wcf-custom-header-with-silverlight/

IClientMessageInspector:

public class HttpUserAgentMessageInspector : IClientMessageInspector

    private const string UserAgentHttpHeader = "user-agent";

    private readonly string _userAgent;

    public HttpUserAgentMessageInspector(string userAgent)
    
        _userAgent = userAgent;
    

    #region IClientMessageInspector Members

    public void AfterReceiveReply(ref Message reply, object correlationState)
    
    

    public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
    
        HttpRequestMessageProperty httpRequestMessage;
        object httpRequestMessageObject;
        if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
        
            httpRequestMessage = (HttpRequestMessageProperty)httpRequestMessageObject;
            if (string.IsNullOrEmpty(httpRequestMessage.Headers[UserAgentHttpHeader]))
            
                httpRequestMessage.Headers[UserAgentHttpHeader] = _userAgent;
            
        
        else
        
            httpRequestMessage = new HttpRequestMessageProperty();
            httpRequestMessage.Headers[UserAgentHttpHeader] = _userAgent;
            request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
        
        return null;
    

    #endregion

IEndpointBehavior:

public class HttpUserAgentEndpointBehavior : IEndpointBehavior

    private readonly string _mUserAgent;

    public HttpUserAgentEndpointBehavior(string userAgent)
    
        _mUserAgent = userAgent;
    

    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    
    

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    
        var inspector = new HttpUserAgentMessageInspector(_mUserAgent);
        clientRuntime.MessageInspectors.Add(inspector);
    

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    
    

    public void Validate(ServiceEndpoint endpoint)
    
    

    #endregion

向代理添加行为。请注意,我已将客户端代理的实例化抽象到此 ClientManager 类中。我的 Silverlight 应用程序有多个服务,这些服务都需要相同的自定义配置,通过这个管理器应用。为简洁起见,我删除了不相关的代码。

public class ClientManager<TClient, TService> : NotificationObject, IClientManager<TClient, TService>
    where TClient : ClientBase<TService>, ICommunicationObject
    where TService : class

    private static IClientFactory _factory = new ClientFactory();
    private TClient _client;

    /// <summary>
    /// Instantiates the manager and the client.
    /// </summary>
    /// <param name="args">The arguments used to construct the client.</param>
    public ClientManager(params object[] args)
    
        try
        
            _client = _factory.Create<TClient, TService>(args);

            // Add custom behavior to support custom HTTP headers
            _client.Endpoint.Behaviors.Add(new HttpUserAgentEndpointBehavior("this is a test"));
        
        catch (Exception exc)
        
            // The factory may throw an exception when it cannot instantiate the client.
            FaultException = exc;
            throw;
        

        Client.Faulted += Client_Faulted;
    

现在,当我运行应用程序时,我在服务对 WCF 服务的第一次调用时收到以下异常

NotSupportedException。 HttpWebRequest 上的“用户代理”标头不是 Silverlight 中支持。

在客户端代理自动生成的代码中:

        public System.IAsyncResult BeginAutoLoginUser(System.AsyncCallback callback, object asyncState) 
            object[] _args = new object[0];
            System.IAsyncResult _result = base.BeginInvoke("AutoLoginUser", _args, callback, asyncState);
            return _result;
        

任何想法为什么这不起作用?

【问题讨论】:

这可能是一个安全限制。 Silverlight 充满了这些。只需尝试设置(不存在的)“user-agent2”标头,看看是否有效。如果是这样,则意味着它只是由于某种原因禁止了特定的标头。 @John 我刚刚又遇到了这个问题。将标头更改为“user-agent2”就可以了。非常感谢!如果您将评论转换为答案,我会投票。否则我会添加我自己的答案。 好吧,我想知道您所说的“成功了”是什么意思。在您的场景中坚持使用“user-agent2”标头或类似的东西是否可以接受? 我创建了自己的标题名称,比“user-agent2”更重要。但是,是的,使用“user-agent”以外的标题名称是可行的。 好的,已提交答案。 【参考方案1】:

您可能无法设置某些标准标头,例如 user-agent,但您仍然可以使用非标准名称(例如 user-agent2)在标头中传输相同的信息。

Silverlight 有很多这样的安全隐患。

【讨论】:

以上是关于Silverlight 不支持 HttpWebRequest 上的标头的主要内容,如果未能解决你的问题,请参考以下文章

Silverlight 4 BitmapImage - bmp 文件支持

Silverlight之我见

狂想成真时,谈Silverlight 2.0

Silverlight 是不是支持 StringFormat 绑定?

使用Selenium Webdriver的Silverlight和Flex应用程序自动化

silverlight与aspx直接交互