6

サード パーティのレポート コンポーネントを使用する ASP.NET サイトがあります。NullReferenceExceptionこのコンポーネントは、クライアント ブラウザがUser-Agentリクエスト ヘッダーで a を指定していない場合は常にa をスローするため、動作が正しくありません。

基本的に、私が回避策を考え出そうとしているのは奇妙なシナリオです。誰/どのクライアントが User-Agent を指定していないかはわかりませんが、これは IMO の形式が悪いように見えますが、それが生成している例外に対処する必要があります。レポート コンポーネントのバグに関してサードパーティにサポート チケットを記録しましたが、そのルートがどれほど実りあるものになるかについては疑問があります。したがって、私の考えは、User-Agentが空白であることを検出し、レポート コンポーネントをなだめるためだけにデフォルトに設定することでした。ただし、Request.Headers コレクションでは何も変更できないようです。次の例外が発生します。

Operation is not supported on this platform.

私はこれを行うことができないだろうと信じ始めています。ASP.NET がこれを許可しない理由は理解していますが、他の回避策は思いつきませんでした。

更新: penfold の提案で、 を使用しUser-Agentて をRequest.Headersコレクションに追加しようとしました。これにより、コレクションに追加されましたが、プロパティは更新されませんでした。これが、レポート コンポーネントが失敗する原因となっています。私は .NET Reflector を調べて、そのプロパティがどのように設定されているかを判断して更新できるようにしましたが、まだ何も思いつきませんでした (プロパティを駆動するプライベート フィールドだけを見つけられるわけではありません)。 )。HttpModuleHeadersRequest.UserAgent

4

3 に答える 3

3

最近、私もあなたと同じような問題に直面しています。Request.UserAgent の問題は、モック HttpWorkerRequest を使用して解決します。

(カスタム HttpModule を使用して Request.Headers のエージェント文字列を既に解決していると仮定します)

サンプルコードは次のとおりです。

Friend Class MockedRequestWorker
    Inherits HttpWorkerRequest

    Private ReadOnly _BaseHttpWorkerRequest As HttpWorkerRequest
    Private ReadOnly _UserAgent As String

    Friend Sub New(ByVal base As HttpWorkerRequest, 
        ByVal UserAgent As String)
        _BaseHttpWorkerRequest = base
        _UserAgent = UserAgent
    End Sub

    Public Overrides Sub EndOfRequest()
        _BaseHttpWorkerRequest.EndOfRequest()
    End Sub

    Public Overrides Sub FlushResponse(ByVal finalFlush As Boolean)
        _BaseHttpWorkerRequest.FlushResponse(finalFlush)
    End Sub

    'Note: remember to override all other virtual functions by direct invoke functions
    'from _BaseHttpWorkerRequest, except the following function

    Public Overrides Function GetKnownRequestHeader(ByVal index As Integer) As String

        'if user is requesting the user agent value, we return the 
        'override user agent string
        If index = HttpWorkerRequest.HeaderUserAgent Then
            Return _UserAgent
        End If

        Return _BaseHttpWorkerRequest.GetKnownRequestHeader(index)
    End Function

End Class

次に、カスタム HttpApplication.BeginRequest ハンドラーでこれを行います

Private Sub BeginRequestHandler(ByVal sender As Object, ByVal e As EventArgs)

    Dim request As HttpRequest = HttpRequest.Current.Request
    Dim HttpRequest_wrField As FieldInfo = GetType(HttpRequest).GetField("_wr", BindingFlags.Instance Or BindingFlags.NonPublic)

    Dim ua As String = "your agent string here"
    Dim _wr As HttpWorkerRequest = HttpRequest_wrField.GetValue(request)
    Dim mock As New MockedRequestWorker(_wr, ua)

    'Replace the internal field with our mocked instance
    HttpRequest_wrField.SetValue(request, mock)

End Sub

注: このメソッドはまだ ServerVariables のユーザー エージェント値を置き換えませんが、必要なもの (および私の問題も) を解決できるはずです。

この助けを願っています:)

于 2014-01-23T15:12:36.777 に答える
3
protected void Application_BeginRequest(Object sender, EventArgs e) {
    const string ua = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
    Request.Headers["User-Agent"] = ua;
    var httpWorkerRequestField = Request.GetType().GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic);
    if (httpWorkerRequestField != null) {
        var httpWorkerRequest = httpWorkerRequestField.GetValue(Request);
        var knownRequestHeadersField = httpWorkerRequest.GetType().GetField("_knownRequestHeaders", BindingFlags.Instance | BindingFlags.NonPublic);
        if (knownRequestHeadersField != null) {
            string[] knownRequestHeaders = (string[])knownRequestHeadersField.GetValue(httpWorkerRequest);
            knownRequestHeaders[39] = ua;
        }
    }
}
于 2015-01-24T08:09:24.757 に答える