如何在WSDL中修改httpAddress?

时间:2014-01-07 10:34:18

标签: asp.net web-services soap wsdl

问题几乎是这样的:ASP.NET Web Service changes port on Invoke。我尝试使用SoapExtensionReflector修改WSDL中的服务地址,它可以在SaopAddress上运行,但http地址仍在进行交换。 结果是这样的:

 - <wsdl:service name="WebService1">
  - <wsdl:port name="WebService1Soap" binding="tns:WebService1Soap">
     <soap:address location="http://I can remove this Port:3821/WebService1.asmx" /> 
    </wsdl:port>
  - <wsdl:port name="WebService1Soap12" binding="tns:WebService1Soap12">
     <soap12:address location="http://I can remove this Port:3821/WebService1.asmx" /> 
    </wsdl:port>
  - <wsdl:port name="WebService1HttpGet" binding="tns:WebService1HttpGet">
     <http:address location="http://localhost:3821/WebService1.asmx" /> 
    </wsdl:port>
  - <wsdl:port name="WebService1HttpPost" binding="tns:WebService1HttpPost">
     <http:address location="http://localhost:3821/WebService1.asmx" /> 
    </wsdl:port>
 </wsdl:service>

我们可以看到soap位置已更改但最后两个http:地址位置仍未更改。

这是我的代码:

  public class OuterPortReflector : SoapExtensionReflector
  {       
    public override void ReflectMethod()
    {            
    }

    public override void ReflectDescription()
    {
        ServiceDescription description = ReflectionContext.ServiceDescription;
        foreach (Service service in description.Services)
        {
            foreach (Port port in service.Ports)
            {
                if (!portsName.ContainsKey(port.Binding.Name))
                {
                    portsName.Add(port.Binding.Name, true);
                }

                foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
                {
                    SoapAddressBinding binding = extension as SoapAddressBinding;
                    if (null != binding)
                    {
                        binding.Location = binding.Location.Replace("http://localhost", "http://I can remove this Port");
                    }
                    else
                    {
                        HttpAddressBinding httpBinding = extension as HttpAddressBinding;
                        if (httpBinding != null)
                        {
                            httpBinding.Location = httpBinding.Location.Replace("http://localhost", "http://I can remove this Port");
                        }
                        else
                        {
                            Soap12AddressBinding soap12Binding = extension as Soap12AddressBinding;
                            if (soap12Binding != null)
                            {
                                soap12Binding.Location = soap12Binding.Location.Replace("http://localhost", "http://I can remove this Port");
                            }
                        }
                    }
                }
            }
        }
    }      
}

如何处理?我的代码有问题吗?

希望somebady可以给我一些建议或关键词.QQ

2 个答案:

答案 0 :(得分:0)

if (null != binding)
if (httpBinding != null)
if (soap12Binding != null)

您可以尝试使用此SoapAddressBinding类定义的Equals(Object)方法,而不是将其直接与null作为字符串进行比较。例如,在您的情况下,使用

if(!binding.Equals(null))
if(!httpbinding.Equals(null))
if (!soap12Binding.Equals(null))

很少有平台不能直接比较字符串,总是在比较字符串时尝试使用Equals()方法。

答案 1 :(得分:0)

我唯一可以完成的方法是使用HttpModule。 In拦截每个请求并更改WSDL的响应。

public class WsdlFixHttpModule : IHttpModule
{
    private static string _webServicesBaseUrl;
    public static WsdlFixHttpModule()
    {
        _webServicesBaseUrl = ConfigurationManager.AppSettings("BaseWebServicesUrl");
    }
    public void Init(HttpApplication context)
    {
        context.EndRequest += (s, e) => OnEndRequest(s, e);
        context.BeginRequest += (s, e) => OnBeginRequest(s, e);
    }
    private void OnBeginRequest(object sender, EventArgs e)
    {
        HttpContext httpContext = HttpContext.Current;
        if ((!string.IsNullOrWhiteSpace(_webServicesBaseUrl) & httpContext.Request.RawUrl.EndsWith("YourService.asmx?wsdl", StringComparison.InvariantCultureIgnoreCase)))
            httpContext.Response.Filter = new StreamWatcher(httpContext.Response.Filter);
    }
    private void OnEndRequest(object sender, EventArgs e)
    {
        HttpContext httpContext = HttpContext.Current;
        if ((!string.IsNullOrWhiteSpace(_webServicesBaseUrl) & httpContext.Request.RawUrl.EndsWith("YourService.asmx?wsdl", StringComparison.InvariantCultureIgnoreCase)))
        {
            string wsdl = httpContext.Response.Filter.ToString();
            wsdl = Regex.Replace(wsdl, @"(?<=address location="")(.*)(?=\/YourService.asmx"")", _webServicesBaseUrl);
            httpContext.Response.Clear();
            httpContext.Response.Write(wsdl);
            httpContext.Response.End();
        }
    }
    public void Dispose()
    {
    }
}

这里是StreamWatcher,用于读取默认响应。

public class StreamWatcher : Stream
{
    private Stream _base;
    private MemoryStream _memoryStream = new MemoryStream();
    public StreamWatcher(Stream stream)
    {
        _base = stream;
    }
    public override void Flush()
    {
        _base.Flush();
    }
    public override int Read(byte[] buffer, int offset, int count)
    {
        return _base.Read(buffer, offset, count);
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        _memoryStream.Write(buffer, offset, count);
        _base.Write(buffer, offset, count);
    }
    public override string ToString()
    {
        return Encoding.UTF8.GetString(_memoryStream.ToArray());
    }
    public override bool CanRead
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    public override bool CanSeek
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    public override bool CanWrite
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    public override long Seek(long offset, SeekOrigin origin)
    {
        throw new NotImplementedException();
    }
    public override void SetLength(long value)
    {
        throw new NotImplementedException();
    }
    public override long Length
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    public override long Position
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
}

并且HttpModule必须位于web.config中的registered