首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WCF Webinvoke给出(400)针对特定服务器的不良请求

WCF Webinvoke给出(400)针对特定服务器的不良请求
EN

Stack Overflow用户
提问于 2020-03-24 08:15:17
回答 2查看 285关注 0票数 1

早上好/晚上好,

我是WCF的新手,并创建了一个示例应用程序。问题是,我将一个json字符串作为请求传递,但得到400:错误的请求错误。我的样本详情如下:

ISampleService.cs:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
    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;
            }
        }
    }
}

主叫功能:

代码语言:javascript
运行
复制
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();
        }
    }
}

在运行应用程序时,我会得到以下错误:

代码语言:javascript
运行
复制
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

我尝试过的是:我已经更改了发送和接收的超时,内容类型是application/json。请求仅引发此服务器的错误。我有另一台服务器,我已经尝试过了,而POST正在传递给服务器。这两台服务器的配置是相同的。当我为错误的服务器运行Fiddler时,POST调用成功。将完全相同的请求从邮递员发送到错误的服务器将获得成功(200 OK)状态,在这两种情况下我都得到了正确的响应。

注意: WEBGET、WEBInvoke DELETE在服务器上正常工作。只有WEBInvoke POST不适用于特定服务器。有人能帮我吗?提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2020-03-25 03:20:07

为什么要使用代理(通道工厂)调用WCF Restful服务?如果确实如此,我们应该使用服务基地址而不是POST URL。此外,服务合同应该与服务器相同。

代码语言:javascript
运行
复制
uri = new Uri(protocol + "://" + servername + ":" + @"/rest") // where is the service port number? also, is the format right?

此代码段应该使用服务基地址来由代理发送请求。

实际上,我们通常在调用由Webhttpbinding创建的WCF服务时,由POSTMan/fiddler发送请求。此外,我们应该使用由URITemplate属性修饰的Uri。

如果问题还存在,请随时告诉我。

票数 0
EN

Stack Overflow用户

发布于 2020-03-25 03:34:55

在我看来,这部分载荷看上去不太对。我换了一行,见下文。

唯一的添加是在recipient.id值周围添加引号。

代码语言:javascript
运行
复制
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>\"," // this line I think was wrong. added quotes around the value
    +"\"type\": \"user\""
        +"},"
+"\"role\": \"VIEWER\""
+"}";
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60827137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档