Görünüşe göre, web referansına yapılan çağrı bir istisna atarsa Tim Carter'ın çözümü çalışmıyor. Ham web rezonansına ulaşmaya çalışıyorum, böylece istisna atıldıktan sonra hata işleyicide (kodda) inceleyebilirim. Ancak, çağrı bir istisna attığında Tim'in yöntemi tarafından yazılan yanıt günlüğünün boş olduğunu buluyorum. Kodu tam olarak anlamıyorum, ancak Tim'in yöntemi .Net'in zaten geçersiz hale getirdiği ve web yanıtını attığı noktadan sonra süreci kesiyor gibi görünüyor.
Düşük seviyeli kodlamayla manuel olarak bir web hizmeti geliştiren bir müşteriyle çalışıyorum. Bu noktada, SOAP formatlı yanıttan ÖNCE yanıta HTML formatlı mesajlar olarak kendi dahili işlem hata mesajlarını ekliyorlar. Tabii ki, automagic .Net web referansı bu konuda patladı. Bir istisna atıldıktan sonra ham HTTP yanıtına ulaşabilirsem, karışık dönen HTTP yanıtı içinde herhangi bir SOAP yanıtını arayabilir ve ayrıştırabilir ve verilerimi tamam alıp almadıklarını bilebilirdim.
Sonra ...
İşte bir yürütmeden sonra bile işe yarayan bir çözüm (yalnızca yanıtın peşindeyim - isteği de alabilirim):
namespace ChuckBevitt
{
class GetRawResponseSoapExtension : SoapExtension
{
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
public override object GetInitializer(Type serviceType)
{
return null;
}
public override void Initialize(object initializer)
{
}
private bool IsResponse = false;
public override void ProcessMessage(SoapMessage message)
{
if (message.Stage == SoapMessageStage.AfterSerialize)
IsResponse = true;
else
IsResponse = false;
}
public override Stream ChainStream(Stream stream)
{
if (IsResponse)
{
StreamReader sr = new StreamReader(stream);
string response = sr.ReadToEnd();
sr.Close();
sr.Dispose();
File.WriteAllText(@"C:\test.txt", response);
byte[] ResponseBytes = Encoding.ASCII.GetBytes(response);
MemoryStream ms = new MemoryStream(ResponseBytes);
return ms;
}
else
return stream;
}
}
}
Yapılandırma dosyasında bunu şu şekilde yapılandırabilirsiniz:
<configuration>
...
<system.web>
<webServices>
<soapExtensionTypes>
<add type="ChuckBevitt.GetRawResponseSoapExtension, TestCallWebService"
priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
"TestCallWebService", kitaplığın adı ile değiştirilmelidir (bu, çalıştığım test konsolu uygulamasının adıdır).
Gerçekten ChainStream'e gitmeniz gerekmemelidir; şu şekilde ProcessMessage'dan daha basit bir şekilde yapabilmelisiniz:
public override void ProcessMessage(SoapMessage message)
{
if (message.Stage == SoapMessageStage.BeforeDeserialize)
{
StreamReader sr = new StreamReader(message.Stream);
File.WriteAllText(@"C:\test.txt", sr.ReadToEnd());
message.Stream.Position = 0;
}
}
SoapMessage.Stream'e bakarsanız, bu noktada verileri incelemek için kullanabileceğiniz salt okunur bir akış olması gerekir. Bu bir hata çünkü eğer akışı okursanız, veri bulunmayan sonraki işlem bombaları hatası (akış sondaydı) ve konumu başa sıfırlayamazsınız.
İlginç bir şekilde, her iki yöntemi de, ChainStream ve ProcessMessage yollarını yaparsanız, ProcessMessage yöntemi, akış türünü ChainStream'de ConnectStream'den MemoryStream'e değiştirdiğiniz için çalışır ve MemoryStream arama işlemlerine izin verir. (ConnectStream'i MemoryStream'e yayınlamayı denedim - izin verilmedi.)
Yani ..... Microsoft, ChainStream türünde arama işlemlerine izin vermeli veya SoapMessage.Stream'i olması gerektiği gibi gerçekten salt okunur bir kopya yapmalıdır. (Kongre üyenize vb. Yazın ...)
Bir nokta daha. Bir istisnadan sonra ham HTTP yanıtını almanın bir yolunu oluşturduktan sonra, yine de tam yanıtı alamadım (bir HTTP algılayıcısı tarafından belirlendiği gibi). Bunun nedeni, geliştirme web hizmetinin HTML hata mesajlarını yanıtın başlangıcına eklediğinde Content-Length başlığını ayarlamamasıydı, bu nedenle Content-Length değeri gerçek yanıt gövdesinin boyutundan daha küçüktü. Elimdeki tek şey İçerik Uzunluğu değerindeki karakter sayısıydı - gerisi eksikti. Açıkçası, .Net yanıt akışını okuduğunda, yalnızca İçerik Uzunluğu sayısını okur ve İçerik Uzunluğu değerinin muhtemelen yanlış olmasına izin vermez. Bu olması gerektiği gibi; ancak Content-Length üstbilgisi değeri yanlışsa, yanıt gövdesinin tamamını almanın tek yolu bir HTTP algılayıcısı kullanmaktır (http://www.ieinspector.com ).