我目前在同一台PC上安装了两个相同的Web服务用于测试目的。第一个服务接收的请求也会被转到第二个服务。我的意图是使用HttpModule来做到这一点。我在application.BeginRequest期间处理请求。
public void AsyncForwardRequest(HttpRequest request)
{
try
{
// Prepare web request...
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(WSaddress);
req.Credentials = CredentialCache.DefaultCredentials;
req.Headers.Add("SOAPAction", request.Headers["SOAPAction"]);
req.ContentType = request.Headers["Content-Type"];
req.Accept = request.Headers["Accept"];
req.Method = request.HttpMethod;
// Send the data.
long posStream = request.InputStream.Position;
long len = request.InputStream.Length;
byte[] buff = new byte[len];
request.InputStream.Seek(0, SeekOrigin.Begin);
if (len < int.MaxValue && request.InputStream.Read(buff, 0, (int)len) > 0)
{
using (Stream stm = req.GetRequestStream())
{
stm.Write(buff, 0, (int)len);
}
request.InputStream.Position = posStream;
DebugOutputStream(request.InputStream);
request.InputStream.Seek(0, SeekOrigin.Begin);
IAsyncResult result = (IAsyncResult)req.BeginGetResponse(new AsyncCallback(RespCallback), req);
}
}
catch (Exception ex)
{
App.Error2(String.Format("RequestDuplicatorModule - BeginRequest; ERROR begin request: {0}", ex.Message), ex);
}
private static void RespCallback(IAsyncResult asynchronousResult)
{
try
{
// State of request is asynchronous.
var req = (HttpWebRequest)asynchronousResult.AsyncState;
WebResponse resp = (HttpWebResponse)req.EndGetResponse(asynchronousResult);
Stream responseStream = resp.GetResponseStream();
System.IO.Stream stream = responseStream;
Byte[] arr = new Byte[1024 * 100];
stream.Read(arr, 0, 1024 * 100);
if (arr.Length > 0)
{
string body = (new ASCIIEncoding()).GetString(arr);
Debug.Print(body);
}
}
catch (WebException ex)
{
App.Error2(String.Format("RequestDuplicatorModule - BeginRequest; ERROR begin request: {0}", ex.Message), ex);
}
}
此(HttpWebResponse)req.EndGetResponse(asynchronousResult)抛出异常:500内部服务器错误并失败。原始请求很顺利。
request.InnerStream: ...
这与Web服务地址有什么不同吗?在我的情况下,他们是: http://localhost/WS/service.asmx HTTP://localhost/WS_replicate/service.asmx
答案 0 :(得分:1)
我至少会实现这一点,以便能够读取状态为500的httpwebrequest的内容:
catch (WebException ex)
{
HttpWebResponse webResponse = (HttpWebResponse)ex.Response;
Stream dataStream = webResponse.GetResponseStream();
if (dataStream != null)
{
StreamReader reader = new StreamReader(dataStream);
response = reader.ReadToEnd();
}
}
虽然没有回答你的问题,我建议有一个简单的amsx来读取请求,并将请求发布到两个不同的Web服务。如果您需要一些代码,请告诉我。
其他优点是asmx将更容易支持开发人员以及处理部署的人员。您可以添加配置选项以使实际网址动态化。
答案 1 :(得分:0)
能够修改AsyncForwardRequest方法,以便我可以实际编辑SoapEnvelope本身:
string buffString = System.Text.UTF8Encoding.UTF8.GetString(buff);
using (Stream stm = req.GetRequestStream())
{
bool stmIsReadable = stm.CanRead; //false, stream is not readable, how to get
//around this?
//solution: read Byte Array into a String,
//modify <wsa:to>, write String back into a
//Buffer, write Buffer to Stream
buffString = buffString.Replace("http://localhost/WS/Service.asmx", WSaddress);
//write modded string to buff
buff = System.Text.UTF8Encoding.UTF8.GetBytes(buffString);
stm.Write(buff, 0, (int)buff.Length);
}