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();
这是客户的要求。
我创建了一个具有登录方法的 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();
这是客户的要求。