none
WCF WEBInvoke POST throwing 400:Bad Request error for a specific server RRS feed

  • Question

  • Good morning/evening,

    I am new to WCF and have created a sample application. The problem is I am passing a json string as a request but getting 400:Bad request error. The details of my sample is given below:

    ISampleService.cs:

        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Linq;
        using System.Runtime.Serialization;
        using System.Runtime.Serialization.Json;
        using System.ServiceModel;
        using System.ServiceModel.Web;
        using System.Text;
        
        namespace SampleWCF
        {
            [ServiceContract]
            public interface ISampleService
            {
                [OperationContract]
                [WebInvoke(UriTemplate = "/folder_entries/{mFileID_param}/shares?notify=true", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
                string AddShareToFileNotify(string mFileID_param, string rqst_param);
            }
        }
        
        
        #region TestSample
        [DataContract]
        public class TestSample
        {
            public TestSample() { }
        
            [DataMember(Name = "recipient")]
            public Recipient Recipient { get; set; }
        
            [DataMember(Name = "role")]
            public String Role { get; set; }
        
            [DataMember(Name = "access")]
            public TestAccess access{ get; set; }
        
            [DataMember(Name = "can_share")]
            public bool CanShare { get; set; }
        
            [DataMember(Name = "days_to_expire")]
            public int DaysToExpire { get; set; }
        
        }
        
            #region TestAccess 
            [DataContract]
            public class TestAccess 
            {
                #region Attributes
        
                [DataMember(Name = "role")]
                public String Role { get; set; }
        
                [DataMember(Name = "rights")]
                public AccessRights AccessRights { get; set; }
        
                #endregion
        
                #region Constructor
                public TestAccess () { }
                #endregion
            }
            #endregion
        
            #region rights
            [DataContract]
            public class AccessRights
            {
                public AccessRights() { }
        
                [DataMember(Name = "testinternal")]
                public Boolean Internal { get; set; }
        
                [DataMember(Name = "testexternal")]
                public Boolean External { get; set; }
        
                [DataMember(Name = "public")]
                public Boolean Public { get; set; }
        
                [DataMember(Name = "max_role")]
                public String Max_Role { get; set; }
        
                [DataMember(Name = "grant")]
                public Boolean Grant { get; set; }
        
            }
            #endregion
        
            #region Recipient
            [DataContract]
            public class Recipient
            {
                public Recipient() { }
        
                [DataMember(Name = "id")]
                public string ID { get; set; }
        
                [DataMember(Name = "type")]
                public string Type { get; set; }
        
            }
            #endregion
        #endregion


    SampleService.svc.cs

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Runtime.Serialization;
        using System.ServiceModel;
        using System.Text;
        using System.ServiceModel.Web;
        using System.ServiceModel.Security;
        using System.Net;
        using System.IO;
        using System.Threading;
        using System.Security.Cryptography.X509Certificates;
        using System.Net.Security;
    
        namespace SampleWCF
        {
            public class SampleService : ISampleService
            {
                private ISampleService client = null;
                private WebChannelFactory<ISampleService> cf = null;
                private Uri uri = null;
                private WebHttpSecurityMode mode = WebHttpSecurityMode.Transport;
                public const string CERTIFICATE_TRUST_STORE_NAME = "Trust";
    
                //Method to Validate if the server certificate is valid or not
                private static bool ValidateServerCertificate(object sender,
                                                              X509Certificate certificate,
                                                              X509Chain chain,
                                                              SslPolicyErrors sslPolicyErrors)
                {
                    bool result = false;
                    X509Store store = null;
    
                    try
                    {
                        // If the certificate is valid signed certificate, return true.
                        if (SslPolicyErrors.None == sslPolicyErrors)
                        {
                            return true;
                        }
    
                        // If there are errors in the certificate chain, look in the certificate store to check
                        // if the user has already trusted the certificate or not.
                        if ((0 != (sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors)) ||
                            (0 != (sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch)))
                        {
                            store = new X509Store(CERTIFICATE_TRUST_STORE_NAME, StoreLocation.CurrentUser);
                            store.Open(OpenFlags.ReadOnly);
                            result = store.Certificates.Contains(certificate);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Could not validate certificate!");
                        result = false;
                    }
                    finally
                    {
                        if (store != null)
                            store.Close();
                    }
    
                    return result;
                }
    
    
                public ISampleService initClient(string servername,
                                                 string protocol,
                                                 string username,
                                                 string password)
                {
                    uri = new Uri(protocol + "://" + servername + ":" + @"/rest");
                    WebHttpBinding binding = new WebHttpBinding();
                    binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    binding.MaxReceivedMessageSize = int.MaxValue;
                    binding.ReceiveTimeout = TimeSpan.FromMinutes(10.0);
                    binding.SendTimeout = TimeSpan.FromMinutes(10.0);
                    System.Net.ServicePointManager.DefaultConnectionLimit = 200;
    
                    binding.Security.Mode = mode;
                    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
    
                    cf = new WebChannelFactory<ISampleService>(binding, uri);
                    cf.Credentials.UserName.UserName = username;
                    cf.Credentials.UserName.Password = password;
    
                    client = cf.CreateChannel();
    
                    System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
                    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
    
                    Thread.Sleep(500);
                    return client;
                }
    
                public string AddShareToFileNotify(string mFileID_param, string rqst_param)
                {
                    using (new OperationContextScope((IContextChannel)client))
                    {
                        string rsp = null;
                        try
                        {
                            rsp = client.AddShareToFileNotify(mFileID_param, rqst_param);
                        }
                        catch (Exception ce)
                        {
                            Console.WriteLine("Exception found!{0}",ce);
                            return rsp;
                        }
                        return rsp;
                    }
                }
            }
        }


    Main Calling function:

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
    
        namespace TriggerMain
        {
            class Program
            {
                static void Main(string[] args)
                {
    
                    string mFileID = "xxxxxx";
                    string rqst = "{"
    +"\"access\":{"
    +"\"role\":\"VIEWER\","
    +"\"sharing\":{"
    +"\"external\":false,"
    +"\"grant\":false,"
    +"\"internal\":false,"
    +"\"max_role\":null,"
    +"\"public\":false"
    
    +"}"
    +"},"
    +"\"can_share\": false,"
            +"\"days_to_expire\": 30,"
    +"\"recipient\": {"
                +"\"id\": <yyyyyy>,"
                +"\"type\": \"user\""
                    +"},"
    +"\"role\": \"VIEWER\""
        +"}";
                    string rsp = null;
    
                    SampleWCF.SampleService sample = new SampleWCF.SampleService();
                    sample.initClient("<URL1.xxx.com>", "https", "<Username>", "<Password>");
                    rsp = sample.AddShareToFileNotify(mFileID, rqst);
                    Console.ReadLine();
                }
            }
        }
    



    While running the application I am getting the following error: 

        Exception found!System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.
           at System.Net.HttpWebRequest.GetResponse()
           at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
           --- End of inner exception stack trace ---
    
        Server stack trace:
           at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory`1 factory, WebException responseException, ChannelBinding channelBinding)
           at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
           at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
           at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
           at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
           at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
           at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    
        Exception rethrown at [0]:
           at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
           at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
           at SampleWCF.ISampleService.AddShareToFileNotify(String mFileID_param, String rqst_param)
           at SampleWCF.SampleService.AddShareToFileNotify(String mFileID_param, String rqst_param) in c:\Users\SBasu\Documents\Visual Studio 2013\Projects\SampleWCF\SampleWCF\SampleService.svc.cs:line 103



    What I have tried : I have changed the timeout for send and receive, the content type is application/json. The request is throwing error for only this server. I have another server in which I have tried and the POST is passing in the server. Both the servers have the same configuration. When I run Fiddler for the erroneous server the POST call succeeds. Sending the exact same request from POSTMAN to the erroneous server gives success (200 OK) status and I am getting proper response in both of these cases. 

    Note: WEBGET, WEBInvoke DELETE are working fine for the server. Only **WEBInvoke POST** is not working for the specific server. Can anybody help me regarding this? Thanks in advance.  

                                                                                                                                                                                                                                        
    Tuesday, March 24, 2020 8:25 AM

All replies

  • There is a MSDN WCF forumn where you can get help.

    https://social.msdn.microsoft.com/Forums/en-US/home?forum=adodotnetentityframework

    • Edited by DA924x Tuesday, March 24, 2020 9:47 AM
    Tuesday, March 24, 2020 9:31 AM
  • HI,
    Why does the service’s implemented class have a client implemented method? Could you please post a complete project?
    How do you host the service? In a console application or IIS?
    It seems that you need to deserialize the rqst json string parameter to an object. Would you mind telling me more details?
    Best Regards
    Abraham Qian
    Wednesday, March 25, 2020 8:55 AM
    Moderator
  • I am hosting the service in console application. 

    Will try deserializing the rqst json string parameter to object and run. Will post my findings as well. :)

    Thursday, March 26, 2020 7:07 AM
  • I have deserialized my request but still not able to find a breakthrough. :(
    Tuesday, March 31, 2020 7:58 AM