system.net.webexception:远程服务器上的错误:(400) 错误请求

system.net.webexception:error on the remote server: (400) bad request

我创建了一个具有登录方法的 wcf 网络服务。这是我的代码: IService1.cs

[ServiceContract]
    public interface IService1
    {
        [OperationContract]

        [WebInvoke( BodyStyle = WebMessageBodyStyle.Wrapped,ResponseFormat =WebMessageFormat.Xml, Method ="POST")]
        bool LoginUserDetails(string name, string pass);
    }

Service1.svc.cs

public class Service1 : IService1
    {
        public bool LoginUserDetails(string name, string pass)
        {
           
            SqlConnection con = new SqlConnection("server=DESKTOP-CPOJ94O\MSSQLSERVER1;database=users;integrated security=true");
            con.Open();
            SqlCommand cmd = new SqlCommand("SELECT username, password FROM hjk where CONVERT(VARCHAR, username)=@username and CONVERT(VARCHAR, password)=@password", con);
            cmd.Parameters.AddWithValue("@username", name);
            cmd.Parameters.AddWithValue("@password", pass);
            bool result = false;
            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                result = true;
                return result;
            }
            else
            {
                result = false;

            }
            return result;
        }
    }

web.config

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfService4.Service1" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="WcfService4.IService1" behaviorConfiguration="web">
          
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    <endpointBehaviors >
      <behavior name="web">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="webHttpBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

然后我尝试在 Xamarin.android 应用程序中使用此服务。在我的主要 activity 中,我写了以下内容:

 EditText editText1 = FindViewById<EditText>(Resource.Id.editText1);
            EditText editText2 = FindViewById<EditText>(Resource.Id.editText2);
            TextView txtview = FindViewById<TextView>(Resource.Id.textView1);
            //System.IO.StreamWriter myWriter = null;
            string txt1 = editText1.Text;
            string txt2 = editText2.Text;
            Button btn = FindViewById<Button>(Resource.Id.button1);
           
            btn.Click += delegate { 
string myRequest = "name=rana&pass=ranahd";
                string myResponse = "";
                string myUrl = "http://192.168.0.104/wcf1/Service1.svc/LoginUserDetails";
                System.IO.StreamWriter myWriter = null;// it will open a http connection with provided url
                System.Net.HttpWebRequest objRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(myUrl);//send data using objxmlhttp object
                objRequest.Method = "PUT";
                //objRequest.ContentLength = TranRequest.Length;
                objRequest.ContentType = "text/xml";//to set content type
                myWriter = new System.IO.StreamWriter(objRequest.GetRequestStream());
                myWriter.Write(myRequest);//send data
                myWriter.Close();//closed the myWriter object
                try
                {
                    System.Net.HttpWebResponse objResponse = (System.Net.HttpWebResponse)objRequest.GetResponse();//receive the responce from objxmlhttp object 
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(objResponse.GetResponseStream()))
                    {
                        myResponse = sr.ReadToEnd();
                    }

                    txtview.Text = myResponse;
                }
                catch(Exception exp)
                {
                    System.Net.WebException exception = new System.Net.WebException();
                    Toast.MakeText(this,exception.Message,ToastLength.Long).Show();
                }
            };

        }

我得到异常:system.net.webexception:远程服务器上的错误:(400) 错误请求。当我在 toast 中阅读消息时,它说:由于对象的当前状态,操作无效。我做了我的研究,但我找不到问题是什么。我做错了什么? 提前致谢。

由于XML格式只有一个根,JSON格式只有一个对象,所以只能向方法传递一个参数。事实上,如果您将服务合同更改为:

  [OperationContract]
  [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
  bool LoginUserDetails(string name, string pass);

服务会抛出异常:

将 WebMessageBodyStyle 更改为 wrapped 并不是解决此异常的最佳方法。

我们应该把用户名和密码封装成一个class:

[DataContract]
public class User {
    [DataMember]
    public string username { get; set; }
    [DataMember]
    public string pass { get; set; }
}

这是界面:

 [OperationContract]
 [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
 bool LoginUserDetails(User user);

我建议您在 WCF 中启用帮助文档:

<webHttp helpEnabled="true"/>

结果

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

更新

这是我的演示:

 [OperationContract]

 [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
 bool LoginUserDetails(User user);

这是服务的界面。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8763/TEST/LoginUserDetails");
            request.Method = "POST";
            request.ContentType = "application/json;charset=UTF-8";
            string Json = "{\"pass\":\"123\",\"username\":\"sdd\"}";
            request.ContentLength = Encoding.UTF8.GetByteCount(Json);
            Stream myRequestStream = request.GetRequestStream();
            StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
            myStreamWriter.Write(Json);
            myStreamWriter.Close();

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            Console.WriteLine(retString);
            Console.ReadKey();

这是客户的要求。