Workaround “The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect” error.

We have a .Net 1.1 application that worked with SQL server 2000. When we changed it to work with sql Server 2005, some calls to SPs returned errors like the following

The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 8 (“@ParamName”): The supplied value is not a valid instance of data type numeric. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision.”

It was found, that C# decimal variable can keep values with more than 4 decimal points (e.g. 43.23232322323) and when it is passes to SP parameter as MONEY, combination .Net 1.1 – SQL Server 2005 doesn’t work.
Note that combination  .Net 1.1 – SQL Server 2000 and  .Net 2.0 – SQL Server 2005  work fine.

To workaround I’ve added simple function to round values before assigning SP parameter

       public static decimal SafeMoney(object attribute)
        {
            decimal decMoney = Convert.ToDecimal(attribute);
            decMoney = Math.Round(decMoney, 4);//required in 1.1 to connect to SQL Server 2005
           return decMoney;
        }

 

 

Unable to run WSDL.exe against Example from Web Services Description Language (WSDL) 1.1

I need to create WSDL file for RPC/Encoding soap implementation.
To learn how to create the WSDL I took an
Example 5. SOAP binding of request-response RPC operation over HTTP from Web Services Description Language (WSDL) 1.1 specification

and tried to run WSDL.exe for the file.

 I have to fix couple simple errors
1. removed
wsdl: from wsdl:arrayType

2. Changed StockQuoteBinding to StockQuoteSoapBinding in  <port name="StockQuotePort" binding="tns:StockQuoteBinding">

And then I’ve got the error:

 The operation ‘GetLastTradePrice’ on portType ‘StockQuotePortType’ from namespace ‘http://example.com/stockquote.wsdl‘ had the following syntax error:  The operation has no matching binding. Check if the operation, input and output names in the Binding section match with the corresponding names in the PortType section.

I gave up to fix the sample from standard specification that doesn't work.
It is quite annoying.

My RegexMatchsHelper class

Previously I’ve posted a few Helper Classes . This post describes my RegexMatchsHelper class

I also added a few related links:

Use Regular Expressions to Constrain Input in ASP.NET

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
 
      ///<summary>
      /// Summary description for RegexMatchs.
      ///</summary>
      public class RegexMatchsHelper
      {
            public RegexMatchsHelper()
            {
                  //
                  // TODO: Add constructor logic here
                  //
            }
 
//          public static void RetrieveMatchedStringTest()
//          {
//                string sResp=StreamHelper.FileToString(“searchManyPages.htm”);
//                string pattern=”tokenKey=(.*?)&target=results_ResultsList”;
//                string sRet=RetrieveMatchedString( sResp, pattern);  
//          }
            //assumed that pattern has something like (.*?) inside
        public static string CaptureFirstUnnamedGroup(string input, string pattern)
        {
            return CaptureFirstUnnamedGroup(input, pattern, RegexOptions.None);
        }
        public static string CaptureFirstUnnamedGroupIgnoreNL(string input, string pattern)
        {
            return CaptureFirstUnnamedGroupIgnoreNL(input, pattern, RegexOptions.None);
        }
        public static string CaptureFirstUnnamedGroupIgnoreNL(string input, string pattern, RegexOptions options)
        {
            //from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/regexnet.asp
            // SingleLine Has nothing to do with how many lines are in the input string. Rather, will cause the . (period) metacharacter to match any character, instead of any character except n, which is the default.
            return CaptureFirstUnnamedGroup(input, pattern, options | RegexOptions.Singleline);
        }
        public static string CaptureFirstUnnamedGroup(string input, string pattern, RegexOptions options)
            {
                  string sRet=“”;
            Regex regex = new Regex(pattern, options);
                  Match m = regex.Match(input);
                  if((m.Success) )
                  {
                        if ((m.Groups.Count>=2) && (m.Groups[1].Captures.Count>0))
                               sRet= m.Groups[1].Captures[0].Value;
                  }
                  FSHelperLib.DebugHelper.TracedLine(” captured “ + sRet );
                  return sRet;
            }
        ///<summary>
        /// Returns array of matched strings
        ///</summary>
        ///<param name=”input”></param>
        ///<param name=”pattern”></param>
        ///<param name=”options”></param>
        ///<returns></returns>
        public static string[] MultipleMatchesFirstUnnamedGroupCaptures(string input, string pattern, RegexOptions options)
        {
            //string sRet = “”;
            Regex regex = new Regex(pattern, options);
            MatchCollection matches = regex.Matches(input);
            string[] asCaptures = new string[matches.Count];
            int i = 0;
            foreach (Match m in matches)
            {
                Debug.Assert(((m.Groups.Count == 2) && (m.Groups[1].Captures.Count > 0)));
                asCaptures[i] = m.Groups[1].Captures[0].Value;
               // FSHelperLib.DebugHelper.TracedLine(” captured ” + sRet);
                i++;
            }
            return asCaptures;
        }
 
    }
 


My StreamHelper class

Previously I’ve posted a few Helper Classes . This post describes my StreamHelper class

    using Microsoft.VisualBasic;
    using System;
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Diagnostics;
 
    public class StreamHelper
    {
 
            //    ‘See also FxLib Author: Kamal Patel, Rick Hodder
            //    ‘Find the first entry of sToFing and returns the string after it
            //    ‘See also FxLib StringExtract (and StuffString)
            // Methods
        public StreamHelper()
        {
        }
#region “Stream and Resources Functions”
            //C# version of FxLib: Extended Functions Library for .NET FXLib
            public static string FileToString(string cFileName)
            {
                  StreamReader oReader = System.IO.File.OpenText(cFileName);
                  string lcString = oReader.ReadToEnd();
                  oReader.Close();
                  return lcString;
            }
            public static string StreamToString(Stream strm)
            {
                  if (strm.CanSeek)
                  {
                        strm.Seek(0, SeekOrigin.Begin);
                  }
                  StreamReader reader1 = new StreamReader(strm);
                  return reader1.ReadToEnd();
            }
      //’another implementation(similar) in http://blog.steeleprice.net/archive/2004/04/06/202.aspx
            public static string ResourceToString(string ResName)
            {
                  Assembly assembly1 = Assembly.GetExecutingAssembly();
                  return ResourceToString(ResName, assembly1);
            }
            //                Assembly assembly1 = Assembly.GetExecutingAssembly();
            public static string ResourceByFullNameToString(string ResourceName,Assembly asm)
            {
                  Stream stream = asm.GetManifestResourceStream(ResourceName);
                  if (stream == null)
                  {
                        throw new ApplicationException(“Couldn’t find embedded resource “ + ResourceName);
                  }
                  return StreamToString(stream);
            }
 
            public static string ResourceToString(string ResName, Assembly Asm)
            {
                  Stream stream1 = GetManifestResourceStream(ResName, Asm);
                  return StreamToString(stream1);
            }
//          ‘ Asm – the current caller assembly.
            public static void ResourceToFile(string ResName, Assembly Asm, string FileName)
            {
                  //object obj1;
                  Stream stream1 = GetManifestResourceStream(ResName, Asm);
                  StreamReader reader1 = new StreamReader(stream1);
                  StreamWriter writer1 = new StreamWriter(FileName, false);
                  writer1.Write(reader1.ReadToEnd());
                  writer1.Close();
                  //return obj1;
            }
        ///<summary>
        /// Inserts Assembly name in fornt of ResName, Should be called from FB assembles only
        ///</summary>
        ///<param name=”ResName”></param>
        ///<param name=”Asm”></param>
        ///<returns></returns>
        public static string ResourceNameWithNamespace(string ResName, Assembly Asm)
        {   //NOTE: If resource is located in subfolder of C# project, path of subfolder should be specified (it is included as part of namespace)
            //’ Resources are named using a fully qualified name (including namespace).
            //assumed that namespace is the same as assembly names
            //TODO use http://www.developersdex.com/gurus/articles/828.asp
            //to find resource even if namespace is not specified
            string sFullName = Asm.GetName().Name + “.” + ResName;
            return sFullName;
        }
        //’if ThrowException=true, then Throw exception if resource not found
        public static bool EnsureManifestResourceExist(string ResName, Assembly Asm, bool ThrowException)
        {   //NOTE: If resource is located in subfolder of C# project, path of subfolder should be specified (it is included as part of namespace)
            //’ Resources are named using a fully qualified name ((including namespace).
            bool bRet=true;  
            ManifestResourceInfo info = Asm.GetManifestResourceInfo(ResName);
            if (info == null)
            {
                bRet=false;
                string sMsg = “Couldn’t find embedded resource “ + ResName + ” in assembly “ + Asm.FullName;
                if (ThrowException)
                {
                    throw new ApplicationException(sMsg);
                }
                else
                {
                    Debug.Assert(false, sMsg);
                }
            }
            return bRet;
        }
 
        //’Throw exception if resource not found
            public static Stream GetManifestResourceStream(string ResName, Assembly Asm)
            {   //NOTE: If resource is located in subfolder of C# project, path of subfolder should be specified (it is included as part of namespace)
                  //’ Resources are named using a fully qualified name ((including namespace).
            //Assume that Default Namespace is the same as Assemebly name
                  string sName = Asm.GetName().Name + “.” + ResName;
                  Stream stream2 = Asm.GetManifestResourceStream(sName);
            if (stream2 == null)//according to ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.en/cpref10/html/M_System_Reflection_Assembly_GetManifestResourceStream_2_42a1d385.htm
                  {// .Net 2 throws exception by itself
                        throw new ApplicationException(“Couldn’t find embedded resource “ + sName);
                  }
                  return stream2;
            }
            public static void SaveToFile(byte[] data, string FileName)
            {
                  StreamWriter writer1 = new StreamWriter(FileName, false);
                  writer1.BaseStream.Write( data,0,data.Length);
                  writer1.Close();
            }
            public static void SaveToFile(Stream strm, string FileName)
            {
                  StreamReader reader = new StreamReader(strm);
                  StreamWriter writer = new StreamWriter(FileName, false);
                  writer.WriteLine(reader.ReadToEnd());
                  writer.Close();
            }
            public static void SaveStringToFile(string sData, string FileName)
            {
                  StreamWriter writer1 = new StreamWriter(FileName, false);
                  writer1.Write( sData );
                  writer1.Close();
            }
            //OBSOLETE: use .Net4 input.CopyTo(output); http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c
            void Copy(Stream fromStream, Stream toStream)
            {
                  StreamReader reader = new StreamReader(fromStream);
                  StreamWriter writer = new StreamWriter(toStream);
                  writer.WriteLine(reader.ReadToEnd());
                  writer.Flush();
            }
 
            #endregion //”Stream and Resources Functions”
 
    }

My HttpWebRequestHelper class

Previously I’ve posted a few Helper Classes . This post describes my HttpWebRequestHelper class:
using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics ;
using System.Net;
 
namespace FSHelperLib
{
      using System;
      using System.Text;
 
//    System.Web.HttpRequest is a class used on the server and inside an ASP.NET application. It represents the *incoming* request from a client.
//   System.Net.HttpWebRequest is a class used to make an *outgoing request to a web application.
 
      //The best ideas come from http://odetocode.com/Articles/162.aspx
 
      ///<summary>
      /// Summary description for HttpWebRequestHelper.
      ///</summary>
      public class HttpWebRequestHelper
      {
            // Methods
            public HttpWebRequestHelper()
            {
            }
        //only cookies returned, actual response is ignored
        public static CookieContainer PostWithCookies(string sUrl, string postData, string saveHtml)
            {    
                  // have a cookie container ready to receive the forms auth cookie
                  CookieContainer cntnrCookies = new CookieContainer();
                  return PostWithCookies(sUrl, postData, saveHtml, ref cntnrCookies);
            }
            //only cookies returned, actual response is ignored
            public static CookieContainer PostWithCookies(string sUrl,string postData,string saveHtml,ref CookieContainer cntnrCookies)
            {                
                  if(cntnrCookies==null)
                  {
                     cntnrCookies = new CookieContainer(); 
                  }
                  HttpWebResponse resp=PostGetHttpWebResponse(sUrl, postData,ref cntnrCookies);
                  DebugHelper.TracedLine(” resp.ResponseURI=” + resp.ResponseUri );
                  Stream strmResponse = resp.GetResponseStream();
                  if (!DataHelper.IsNullOrEmpty(saveHtml))
                              StreamHelper.SaveToFile(strmResponse,saveHtml);
                  DebugHelper.PrintCookies(new Uri(sUrl),cntnrCookies);
                  return      cntnrCookies;
            }
 
            public static HttpWebResponse PostGetHttpWebResponse(string sUrl,string postData,ref CookieContainer cntnrCookies)
            {
           
                  //from http://odetocode.com/Articles/162.aspx
     
            HttpWebRequest webRequest = PreparePostRequest(sUrl, postData, cntnrCookies);
                  HttpWebResponse resp=webRequest.GetResponse() as HttpWebResponse;
            //from http://www.codeproject.com/csharp/clientticket_msnp9.asp
            while((resp.StatusCode == HttpStatusCode.Redirect) )//add? || (resp.StatusCode == HttpStatusCode.Moved ) )
                  {// If the statuscode is 302, then there is a redirect, read the new adres en connect again
                string uri = resp.Headers.Get(“Location”);
                // Make a new request
                webRequest = (HttpWebRequest)HttpWebRequest.Create(uri); //get, not post
                webRequest.CookieContainer = cntnrCookies;
                //try to change extra options if required – from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         
                resp = (HttpWebResponse)webRequest.GetResponse();
            }
                  DebugHelper.PrintHttpWebResponse(resp,TraceHelper.LineWithTrace(“”));
                  DebugHelper.PrintCookies(webRequest.RequestUri,cntnrCookies);
                  //DebugHelper.PrintCookies(resp.Cookies,”Response.Cookies” );
                  return      resp;
            }
        private static HttpWebRequest PreparePostRequest(string sUrl, string postData, CookieContainer cntnrCookies)
        {
            //from http://odetocode.com/Articles/162.aspx
            // first, request the login form to get the viewstate value
 
            // now post to the login form
            HttpWebRequest webRequest = PrepareWebRequest(sUrl, “POST”, cntnrCookies);
            // write the form values into the request message
            StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
            requestWriter.Write(postData);
            requestWriter.Close();
            return webRequest;
        }
        //The Method property can be set to any of the HTTP 1.1 protocol verbs: GET, HEAD, POST, PUT, DELETE, TRACE, or OPTIONS.
        public static HttpWebRequest PrepareWebRequest(string sUrl, string Method, CookieContainer cntnrCookies)
        {
            HttpWebRequest webRequest = WebRequest.Create(sUrl) as HttpWebRequest;
            webRequest.Method = Method;
            webRequest.ContentType = “application/x-www-form-urlencoded”;
            webRequest.CookieContainer = cntnrCookies;
            /*                //try to change – from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         
                        webRequest.AllowAutoRedirect = false;
                       webRequest.Pipelined = false;
                        webRequest.KeepAlive = false;
                        webRequest.ProtocolVersion = new Version(1,0);//protocol 1.0 works better that 1.1 ??
            */
            //MNF 26/5/2005 Some web servers expect UserAgent to be specified
            //so let’s say it’s IE6
            webRequest.UserAgent = “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)”;
 
            DebugHelper.PrintHttpWebRequest(webRequest, TraceHelper.LineWithTrace(“”));
            return webRequest;
        }
        public static string PostGetResponseString(string sUrl, string postData, ref CookieContainer cntnrCookies, string saveHtml)
            {                
                  HttpWebResponse resp=PostGetHttpWebResponse(sUrl, postData,ref cntnrCookies);
            string sResp = GetResponseString(resp, saveHtml);
                  return sResp;
            }
 /// <summary>
       ///
       /// </summary>
       /// <param name=”sUrl”></param>
       /// <param name=”Method”> verbs: GET, HEAD, POST, PUT, DELETE,
TRACE, or OPTIONS.</param>
       /// <param name=”cntnrCookies”>can be null </param>
       /// <param name=”sFileToSaveHtml”>specify null, if in production</param>
       /// <returns></returns>
       /// <example>
       /// HttpWebRequestHelper.GetResponseString (“https://MySite/default.aspx?EntryPoint=1111“, “GET”, null, “temp.htm”);
       /// </example>
        public static string GetResponseString(string sUrl, string Method, CookieContainer cntnrCookies, string sFileToSaveHtml)
        {
            HttpWebRequest webRequest = HttpWebRequestHelper.PrepareWebRequest(sUrl, Method, cntnrCookies);
            HttpWebResponse resp = webRequest.GetResponse() as HttpWebResponse;
            return HttpWebRequestHelper.GetResponseString(resp, sFileToSaveHtml);
        }
        public static string GetResponseString(HttpWebResponse resp, string saveHtml)
        {
            string sResp = StreamHelper.StreamToString(resp.GetResponseStream());
            resp.Close();
            if (!DataHelper.IsNullOrEmpty(saveHtml))
            {
                StreamHelper.SaveStringToFile(sResp, saveHtml);
            }
            return sResp;
        }
        public static bool CookieExists(string sUrl, CookieContainer container, string name)
            {
                  return CookieExists( new Uri( sUrl) , container, name);
            }
            public static bool CookieExists( Uri uri ,CookieContainer container, string name)
            {
                  if (container==null)
                  {
                        return false;
                  }
                  System.Net.CookieCollection cookies = container.GetCookies(uri);
                  return CookieExists(cookies,name );
            }
            public static bool CookieExists(CookieCollection cookies, string name)
            {
                  return (cookies[name]!=null);
            }
        public static string ExtractViewState(string sHtml)
        { //another implementation is in http://odetocode.com/Articles/162.aspx
            string sRet = “”;
            try
            {
                String sPattern = @”name=””__VIEWSTATE””.value=””(.*?)”””;// name=”__VIEWSTATE”.value=”(.*?)”
                sRet = RegexMatchsHelper.CaptureFirstUnnamedGroup(sHtml, sPattern);
                //can return empty viewstate
                //if (String.IsNullOrEmpty(sRet))
                //{
                //    throw new FSCSharpLib.ExceptionWithDetails(“The returned html has unexpected format”, “html: ” + sHtml);
                //}
            }
            catch (Exception exc)
            {
                throw new FSCSharpLib.ExceptionWithDetails(“The returned html has unexpected format”, “html: “ + sHtml, exc);
            }
            //From http://odetocode.com/Articles/162.aspx:
            //Notice the use of URL encoding to make sure the server misinterprets no characters with a special meaning (like the equal sign).
            return System.Web.HttpUtility.UrlEncodeUnicode(sRet);
        }
        //Default method is Get, do not store cookies
        public static Stream GetResponseStream(string sUrl, IWebProxy proxy)
        {
            HttpWebRequest webRequest = WebRequest.Create(sUrl) as HttpWebRequest;
          // webRequest.ContentType = “application/x-www-form-urlencoded”;//is good?
            webRequest.Proxy = proxy;
                  //you can change some properties if required – from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         
            //MNF 26/5/2005 Some web servers expect UserAgent to be specified,so let’s say it’s IE6
            webRequest.UserAgent = “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)”;
            DebugHelper.PrintHttpWebRequest(webRequest, TraceHelper.LineWithTrace(“”));
            HttpWebResponse resp = webRequest.GetResponse() as HttpWebResponse;
            Stream strm   = resp.GetResponseStream();
            return strm;//’HttpWebRequestHelper.GetResponseString(resp, sFileToSaveHtml);
        }
 
      }// class HttpWebRequestHelper
}
 
 
 

How to create .Net SOAP client for apache web service?

I tried to find Tools to generate WSDL from SOAP Sample, but wasn’t successful.

I’ve started to use WSCF – Web services Contract-First to generate WSDL from XSD, that I’ve created manually , but I have the next problem.  The SOAP example uses collections vector (with apache namespace) and I am not sure how specify them in WSDL to generate expected SOAP messages. Someone suggested  “specify a struct in your wsdl file that contains whatever information your vector objects contain, and return an array of these” but I am not sure, would it help.

I tried to follow Visual Basic .NET Client for Apache SOAP article.

Some other links that I’ve read:
SOAP Interoperability with Microsoft and Apache Toolkits – A step by step guide

Web Services between .NET, Java and MS SOAP Toolkit: Part I

From MSDN Web Services Integration  I found tht for apache web service expected RPC/Encoded messages(See 

Which style of WSDL should I use? FOR MORE DETAILS). From   Web Services Description Language (WSDL) 1.1 specification and

The Difference Between RPC and Document Style WSDL  I found that you can specify

<soap:binding style=”rpc” > and

<soap:body use=”encoded” >.
Unfortunately WSCF – Web services Contract-First  doesn’t allow to specify style/use, and I had to modify it manually .
More examples about RPC/ENCODED styles can be found in Mapping between Java language, WSDL and XML for JAX-RPC applications

Related Discussions:XmlSerializer and SOAP/RPC encoding

specify the type inside an apachesoap:Vector type

I had a lot of problems trying to create WSDL file for RPC/Encoding soap implementation to be acceptable by WSDL.exe.

Related Discussion :WSDL Code Generation . Note that sample ASPX Client of AXIS Web Service  works with documents, not with RPC/Encoded.

Finally I was able to create WSDL file with RPC/Encoding soap implementation, however the structure of SOAP messages created accorfing to WSDL is different to SOAP messages,expected by web service.

I gave up with using WSDL and decided to create and parse SOAP messages in code using plain XML DOM. And it is quite easy and quicker.

Lessons learned:  If you don’t have WSDL file for service and do not have automated tool to create it, do NOT try to create it manually(unless it is trivial). It takes too much time. Using XML DOM is a simple alternative and it is fully under your control, easier to debug and maintain.