CopyPastor

Detecting plagiarism made easy.

Score: 1.8353593689945011; Reported for: String similarity, Exact paragraph match Open both answers

Possible Plagiarism

Reposted on 2024-04-16
by Vitaly Filatenko

Original Post

Original - Posted on 2024-04-16
by Vitaly Filatenko



            
Present in both answers; Present only in the new answer; Present only in the old answer;

There are few solution, I will sort them from simplicity to accuracy. :)
1. Don't worry about URLs in WSDL. **Just use `Url` property** on a client side, like in that case:
``` public class MyWebService : RemoteService { public MyWebService() : base() { Url = ConfigurationManager.AppSettings["MyServiceCustomUrl"]; } } ```
Obvious drawback: most probably you will not able to test the service properly using generated html (I mean generated forms for web methods).
2. **Use custom `wsdlHelpGenerator`**.
I didn't test this solution, but at a glance it looks simply enough if you create your own based on original **DefaultWsdlHelpGenerator.aspx** (you can find it in *C:\Windows\Microsoft.NET\Framework\** folders, in my case it was *C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\DefaultWsdlHelpGenerator.aspx*).
3. Use `soapExtensionReflectorTypes`. You already did that.
A drawback: no control over HttpPost/HttpGet protocols.
4. **Implement IIS rewrite module**. It will allow you to modify any output produced by your service. Can be used together with #3.
Create 2 classes, stream decorator:
``` public class StreamWatcher : Stream { private readonly Stream _base; private readonly 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 => _base.CanRead;
public override bool CanSeek => _base.CanSeek;
public override bool CanWrite => _base.CanWrite;
public override long Seek(long offset, SeekOrigin origin) => _base.Seek(offset, origin);
public override void SetLength(long value) => _base.SetLength(value);
public override long Length => _base.Length;
public override long Position { get => _base.Position; set => _base.Position = value; } } ``` and the module: ``` public class WsdlFixHttpModule : IHttpModule { 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 (httpContext.Request.Url.Query.Equals("?WSDL", StringComparison.InvariantCultureIgnoreCase) || IsAsmxGetRequest(httpContext)) { httpContext.Response.Filter = new StreamWatcher(httpContext.Response.Filter); } }
private void OnEndRequest(object sender, EventArgs e) { HttpContext httpContext = HttpContext.Current; string oldValue = "", newValue = ""; bool replacementRequired = false;
if (httpContext.Request.Url.Query.Equals("?WSDL", StringComparison.InvariantCultureIgnoreCase)) { oldValue = ":address location=\"http://"; newValue = ":address location=\"https://"; replacementRequired = true; } else if (IsAsmxGetRequest(httpContext)) { oldValue = "<form target=\"_blank\" action='http://"; newValue = "<form target=\"_blank\" action='https://"; replacementRequired = true; }
if (replacementRequired) { string wsdl = httpContext.Response.Filter.ToString(); wsdl = wsdl.Replace(oldValue, newValue); httpContext.Response.Clear(); httpContext.Response.Write(wsdl); httpContext.Response.End(); } }
private static bool IsAsmxGetRequest(HttpContext httpContext) { return httpContext.Response.ContentType == "text/html" && httpContext.Request.CurrentExecutionFilePathExtension.Equals(".asmx", StringComparison.InvariantCultureIgnoreCase) && httpContext.Request.HttpMethod == "GET"; }
public void Dispose() { } } ```
Then register the module in web.config: ``` <system.webServer xdt:Transform="Insert"> <modules> <!-- Required to replace http in addresses for HttpPost/HttpGet protocols --> <add name="WsdlFixHttpModule" type="MyWebServices.WsdlFixHttp.WsdlFixHttpModule, MyWebServices"/> </modules> </system.webServer> ``` Please note, the registration above is for integration mode, for classic one you need to register it inside `system.web`.

So, in our legacy project I used 3+4 approach, but if I'd want to do that again, I will try to use #2 approach instead. :)
There are few solution, I will sort them from simplicity to accuracy. :)
1. Don't worry about URLs in WSDL. **Just use `Url` property** on a client side, like in that case:
``` public class MyWebService : RemoteService { public MyWebService() : base() { Url = ConfigurationManager.AppSettings["MyServiceCustomUrl"]; } } ```
Obvious drawback: most probably you will not able to test the service properly using generated html (I mean generated forms for web methods).
2. **Use custom `wsdlHelpGenerator`**.
I didn't test this solution, but at a glance it looks simply enough if you create your own based on original **DefaultWsdlHelpGenerator.aspx** (you can find it in *C:\Windows\Microsoft.NET\Framework\** folders, in my case it was *C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\DefaultWsdlHelpGenerator.aspx*).
3. Use `soapExtensionReflectorTypes`. It will allow you to do anything with your HttpSoap protocol addresses.
Create a handler (sample below will change http to https):
``` public class HttpsReflector : SoapExtensionReflector { public override void ReflectMethod() { // nothing to override }
public override void ReflectDescription() { ServiceDescription description = ReflectionContext.ServiceDescription; foreach (System.Web.Services.Description.Service service in description.Services) { foreach (Port port in service.Ports) { foreach (ServiceDescriptionFormatExtension extension in port.Extensions) { if (extension is SoapAddressBinding binding) { binding.Location = binding.Location.Replace("http://", "https://"); } } } } } } ```
Register it in web.config: ``` <system.web> <webServices> <soapExtensionReflectorTypes> <!-- Required to replace http in addresses for HttpSoap protocol --> <add type="MyWebServices.WsdlFixHttp.HttpsReflector, MyWebServices"/> </soapExtensionReflectorTypes> </webServices> </system.web> ```
A drawback: no control over HttpPost/HttpGet protocols.
4. **Implement IIS rewrite module**. It will allow you to modify any output produced by your service. Can be used together with #3.
Create 2 classes, stream decorator:
``` public class StreamWatcher : Stream { private readonly Stream _base; private readonly 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 => _base.CanRead;
public override bool CanSeek => _base.CanSeek;
public override bool CanWrite => _base.CanWrite;
public override long Seek(long offset, SeekOrigin origin) => _base.Seek(offset, origin);
public override void SetLength(long value) => _base.SetLength(value);
public override long Length => _base.Length;
public override long Position { get => _base.Position; set => _base.Position = value; } } ``` and the module: ``` public class WsdlFixHttpModule : IHttpModule { 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 (httpContext.Request.Url.Query.Equals("?WSDL", StringComparison.InvariantCultureIgnoreCase) || IsAsmxGetRequest(httpContext)) { httpContext.Response.Filter = new StreamWatcher(httpContext.Response.Filter); } }
private void OnEndRequest(object sender, EventArgs e) { HttpContext httpContext = HttpContext.Current; string oldValue = "", newValue = ""; bool replacementRequired = false;
if (httpContext.Request.Url.Query.Equals("?WSDL", StringComparison.InvariantCultureIgnoreCase)) { oldValue = ":address location=\"http://"; newValue = ":address location=\"https://"; replacementRequired = true; } else if (IsAsmxGetRequest(httpContext)) { oldValue = "<form target=\"_blank\" action='http://"; newValue = "<form target=\"_blank\" action='https://"; replacementRequired = true; }
if (replacementRequired) { string wsdl = httpContext.Response.Filter.ToString(); wsdl = wsdl.Replace(oldValue, newValue); httpContext.Response.Clear(); httpContext.Response.Write(wsdl); httpContext.Response.End(); } }
private static bool IsAsmxGetRequest(HttpContext httpContext) { return httpContext.Response.ContentType == "text/html" && httpContext.Request.CurrentExecutionFilePathExtension.Equals(".asmx", StringComparison.InvariantCultureIgnoreCase) && httpContext.Request.HttpMethod == "GET"; }
public void Dispose() { } } ```
Then register the module in web.config: ``` <system.webServer xdt:Transform="Insert"> <modules> <!-- Required to replace http in addresses for HttpPost/HttpGet protocols --> <add name="WsdlFixHttpModule" type="MyWebServices.WsdlFixHttp.WsdlFixHttpModule, MyWebServices"/> </modules> </system.webServer> ``` Please note, the registration above is for integration mode, for classic one you need to register it inside `system.web`.

So, in our legacy project I used 3+4 approach, but if I'd want to do that again, I will try to use #2 approach instead. :)

        
Present in both answers; Present only in the new answer; Present only in the old answer;