I've created a wcf webservice that has a login method. this is my code: 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>
then I tried to consume this service in Xamarin.android app. in my main activity I wrote the following:
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();
}
};
}
I got the exception: system.net.webexception:error on the remote server: (400) bad request. and when I read the message in the toast it said: operation is not valid due to current state of the object. I did my research but I couldn't find what the problem was. what did I do wrong? thanks in advance.
Since the XML format has only one root and the JSON format has only one object, only one parameter can be passed to the method. In fact, if you changed a service contract to something like:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
bool LoginUserDetails(string name, string pass);
a service would throw a exception:
Changing WebMessageBodyStyle to wrapped is not the best way to solve this exception.
We should encapsulate username and password into a class:
[DataContract]
public class User {
[DataMember]
public string username { get; set; }
[DataMember]
public string pass { get; set; }
}
This is interface:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
bool LoginUserDetails(User user);
I suggest you enable the help document in WCF:
<webHttp helpEnabled="true"/>
Results
Feel free to let me know if the problem persists.
UPDATE
This is my demo:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
bool LoginUserDetails(User user);
This is the interface of the service.
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();
This is the client's request.