简体   繁体   中英

How to Call asmx service without adding service reference in C#.Net

I am working on calling asmx webservice method without adding service reference as asmx doesn't provide wsdl. I can access asmx service from fiddler as well as from postman. It works fine. However when I try to call it from my C# code it throws 403 forbidden exception.

Below is my c# code.

internal class Class3
{
    string _soapEnvelope =
    @"<soap:Envelope
        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xmlns:xsd='http://www.w3.org/2001/XMLSchema'
        xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
    <soap:Body></soap:Body></soap:Envelope>";

    private string CreateSoapEnvelope()
    {
        Dictionary<string, string> Params = new Dictionary<string, string>();
        Params.Add("aId", "11"); // Add parameterName & Value to dictionary
        Params.Add("cId", "22");
        Params.Add("lId", "20");
        string MethodCall = "<" + "GetSettings" + @" xmlns=""http://tempuri.org/"">";
        string StrParameters = string.Empty;
        foreach (var param in Params)
        {
            StrParameters += string.Format("<{0}>{1}</{0}>", param.Key, param.Value);
        }
        MethodCall = MethodCall + StrParameters + "</" + "GetSettings" + ">";
        StringBuilder sb = new StringBuilder(_soapEnvelope);
        sb.Insert(sb.ToString().IndexOf("</soap:Body>"), MethodCall);
        return sb.ToString();
    }

    private HttpWebRequest CreateWebRequest()
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("sample.asmx");
        webRequest.Headers.Add("SOAPAction", "\"http://tempuri.org/" + "GetSettings" + "\"");
        webRequest.Headers.Add("To", "sample.asmx");
        webRequest.Credentials = CredentialCache.DefaultCredentials;
        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9";
        webRequest.Host = "sample.com";
        webRequest.Headers.Set(HttpRequestHeader.CacheControl, "max-age=0");
        webRequest.Headers.Add("Upgrade-Insecure-Requests: 1");
        webRequest.Headers.Add("Origin", "null");
        webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
        webRequest.Headers.Add("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6");
        webRequest.Method = "POST";
        return webRequest;

    }

    public string InvokeService()
    {
        try
        {
            WebResponse response = null;
            string strResponse = "";
            //Create the request
            HttpWebRequest req = this.CreateWebRequest();
            //write the soap envelope to request stream
            using (Stream stm = req.GetRequestStream())
            {
                using (StreamWriter stmw = new StreamWriter(stm))
                {
                    stmw.Write(this.CreateSoapEnvelope());
                }
            }
            //get the response from the web service
            response = req.GetResponse();
            Stream str = response.GetResponseStream();
            StreamReader sr = new StreamReader(str);
            strResponse = sr.ReadToEnd();
            return HttpUtility.HtmlDecode(strResponse);
        }
        catch (Exception ex)
        {
            return "";
        }
    }

    
}

 internal class Program
{
    static void Main(string[] args)
    {   
        new Class3().InvokeService();
    }
}

Tried adding below headers as well but it doesnt make any difference.

 webRequest.ContentLength = 600000;
        webRequest.ProtocolVersion = HttpVersion.Version11;
        webRequest.KeepAlive = false; 
        webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36";

I am using VS2022 - Console Application with.Net Framework 4.6.2

Can somebody please help me understand what am I doing wrong here.

after lot of research I got to know that the way I am passing parameters were incorrect. Below is the simple and correct version of doing same. Its working now

            string remoteUrl = "service.asmx";
        string poststring = "aId=11&cId=22&lId=20";

        HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(remoteUrl);
        httpRequest.Host = "host.com";
        httpRequest.Method = "POST";
        httpRequest.ContentType = "application/x-www-form-urlencoded";
        httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.127 Safari/537.36";

        // Convert the post string to a byte array
        byte[] bytedata = System.Text.Encoding.UTF8.GetBytes(poststring);
        httpRequest.ContentLength = bytedata.Length;

        // Create the stream
        Stream requestStream = httpRequest.GetRequestStream();
        requestStream.Write(bytedata, 0, bytedata.Length);
        requestStream.Close();

        // Get the response from remote server
        HttpWebResponse httpWebResponse = (HttpWebResponse)httpRequest.GetResponse();
        Stream responseStream = httpWebResponse.GetResponseStream();

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        using (StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                sb.Append(line);
            }
        }

        string data = sb.ToString();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM