0

HttpListener や TcpListener などの要素を呼び出さずに、プロキシ サーバーの機能/アクションをシミュレートするにはどうすればよいですか? C# アプリケーション内からそれらを生成するにはどうすればよいですか?

C# アプリケーションの WebBrowser 要素に実際のデータをストリーミングして戻すことはできましたが、結果を表示するとエラーが発生します。その理由は、私が LITERAL 文字列を表示していて、相対 URI を介してオブジェクトを参照する結果の HTML ストリーム内に JS/CSS コンポーネントがあるためです。明らかに、私のソリューションはそれらがローカルであると考えているため、それらを解決できません。

プロキシのような機能がありません。ストリームをモック ブラウザに渡して適切に表示する必要があります。ただし、C# で構築されたサンプル プロキシ サーバー コードを見ると、それらはすべてリスナーを使用するサーバーとして構築されています。リスニング インターフェイスを作成する必要なく、ローカルでインスタンス化できるものにしたいと考えています。

さて、なぜ私がこれをやろうとしているのか不思議に思うかもしれません。いくつかの理由があります。

  • 内部 Web サーバーをテストできるようにアドホックにヘッダーを挿入できるようにするため
  • 他の .NET コンポーネントから HTTP または HTTPS ストリームを受け取り、さらに他の .NET コンポーネントからヘッダーを挿入できるヘッドレス (GUI なし) コンポーネントとして実行する。
  • これを実装するまではわからないかもしれないと思う他のバックエンドのもの。

これが私がこれまでに持っているものです:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.Net;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            WebClient client = new WebClient();
            var baseUrl = new Uri(textBox1.Text);
            client.Headers.Add("Token1", textBox2.Text);
            client.Headers.Add("Token2",textBox3.Text);

            byte[] requestHTML = client.DownloadData(textBox1.Text);
            string sourceHTML = new UTF8Encoding().GetString(requestHTML);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
            htmlDoc.LoadHtml(sourceHTML);

            //"//*[@background or @lowsrc or @src or @href]"    
            foreach (HtmlNode link in htmlDoc.DocumentNode.SelectNodes("//*[@href]"))
            {
                //Console.Out.WriteLine(link.ToString());
                if (!string.IsNullOrEmpty(link.Attributes["href"].Value))
                {
                    HtmlAttribute att = link.Attributes["href"];
                    Console.WriteLine("Before: " + att.Value);
                    //Console.Out.WriteLine(att.Value.ToString());
                    Console.WriteLine(new Uri(baseUrl, att.Value));
                    link.Attributes["href"].Value = new Uri(baseUrl, att.Value).ToString();
                    Console.WriteLine("After: " + link.Attributes["href"].Value);

                    //att.Value = this.AbsoluteUrlByRelative(att.Value);
                }
            }

            foreach (HtmlNode link2 in htmlDoc.DocumentNode.SelectNodes("//*[@src]"))
            {
                //Console.Out.WriteLine(link.ToString());
                if (!string.IsNullOrEmpty(link2.Attributes["src"].Value))
                {
                    HtmlAttribute att = link2.Attributes["src"];
                    Console.WriteLine("Before: " + att.Value);
                //    //Console.Out.WriteLine(att.Value.ToString());
                    Console.WriteLine(new Uri(baseUrl, att.Value));
                    if (!att.Value.Contains("/WS"))
                    {
                        Console.WriteLine("HIT ME!");
                        var output = "/WS/" + att.Value;
                        link2.Attributes["src"].Value = new Uri(baseUrl, output).ToString();
                        Console.WriteLine("After HIT: " + link2.Attributes["src"].Value);
                    }
                    else
                    {
                        link2.Attributes["src"].Value = new Uri(baseUrl, att.Value).ToString();
                        Console.WriteLine("After: " + link2.Attributes["src"].Value);
                    }


                //    //att.Value = this.AbsoluteUrlByRelative(att.Value);
                }
            }

            Console.WriteLine(htmlDoc.DocumentNode.OuterHtml);
            Console.WriteLine("+========================+");
            webBrowser1.DocumentText = htmlDoc.DocumentNode.OuterHtml;

        }
    }
}

繰り返しますが、これは単なるプロトタイプ コードであるため、おかしなスペースやコメントはご容赦ください。最終的には、よりフォーマルになります。今、この猿が私の背中を殺している。

4

1 に答える 1

0

似たようなものを使ってみNMockませんか?それは、モックを注入できるようにインターフェースを導入する必要があることを意味しますが、それでも他のほとんどの方法でそれを行うよりも優れています、私見...

NMockサイトから:

NMockは、.NET用の動的モックオブジェクトライブラリです。モックオブジェクトを使用すると、他のすべてのコンポーネントの実際の実装に依存することなく、単一のコンポーネント(多くの場合単一のクラス)を簡単にテストできます。これは、オブジェクトのツリー全体ではなく、1つのクラスだけをテストでき、バグをより明確に特定できることを意味します。モックオブジェクトは、テスト駆動開発中によく使用されます。

プロキシサーバーを多かれ少なかれ次のようにモックします。

var mocks = new Mockery();
var mockProxyServer = mocks.NewMock<IMyProxyServer>();

それがあなたがする必要があるすべてです。ご覧のとおり、これはインターフェースに依存します。しかし、通常、私がする必要があるのは、VSの関連するクラスからリファクタリング->インターフェイスを抽出することだけです。

シミュレーションの設定は通常、次のような単体テストのコンテキスト内で行われます。

public class TransferFundsPresenterTest
{
    private Mockery mocks;
    private IMyProxyServer mockProxyServer

    [SetUp]
    public void SetUp()
    {
        mocks = new Mockery();
        mockProxyServer = mocks.NewMock<IMyProxyServer>();
    }

    [Test]
    public void TestProxyFunction()
    {
        Expect.Once.On(mockProxyServer).
            Method("ProxyFunctionA").
            With("1234").   //  <-- simulate the input params here
            Will(Return.Value("Test"));  // <-- simulate the output from server here
    }

これは単なる基本的な例です。あなたはもっとたくさんのことができます、それは非常に柔軟なライブラリです。

あなたは本当にNMockサイトを見る必要があります、それはライブラリに完全に慣れるのはかなり簡単です。

http://www.nmock.org/index.html

于 2012-08-24T02:52:04.053 に答える