jtmerch
asked on
WCF Web Service return raw json
Hello, I am looking to migrate a simple json login function from asmx to WCF. Of course this was much easier in asmx but I'm migrating as I hear that WCF is much better, but I need to at least get this working. Basically I'm using VS2010 and have added an AJAX enabled WCF service. My code works when I serialize the returned value but it returns .d along with escaped characters and I need for it to return JSON. Here is my code:
<ServiceContract(Namespace :="loginwe bsvc")>
<AspNetCompatibilityRequir ements(Req uirementsM ode:=AspNe tCompatibi lityRequir ementsMode .Allowed)>
Public Class openapiwfc
Dim ds As New DataSet
Dim dt As New DataTable
' To use HTTP GET, add <WebGet()> attribute. (Default ResponseFormat is WebMessageFormat.Json)
' To create an operation that returns XML,
' add <WebGet(ResponseFormat:=We bMessageFo rmat.Xml)> ,
' and include the following line in the operation body:
' WebOperationContext.Curren t.Outgoing Response.C ontentType = "text/xml"
<OperationContract()> _
<WebInvoke(ResponseFormat: =WebMessag eFormat.Js on)> _
<WebMethod(EnableSession:= True)> _
Public Function LoginAuth(ByVal email As String, ByVal password As String)
Dim txtItems As New List(Of Object)
'ADO.Net
Dim strCn As String = System.Configuration.Confi gurationMa nager.AppS ettings("C onnectDB")
'"data source=.;Initial Catalog=MyDB;Integrated Security=True"
Dim cn As New SqlClient.SqlConnection()
cn.ConnectionString = strCn
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = cn
cmd.CommandType = CommandType.Text
If email = "" Then
email = "none"
End If
If password = "" Then
password = "none"
End If
Dim grabUserid As String = ""
Dim FoundId As Integer
cmd.CommandText = "SELECT Id, Email, Password from tbluser WHERE Email=@Email AND Password=@Password AND UserActive ='Yes'"
cmd.Parameters.AddWithValu e("@Email" , email)
cmd.Parameters.AddWithValu e("@Passwo rd", Encryption.Encrypt(passwor d))
Try
cn.Open()
cmd.ExecuteNonQuery()
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
dt = ds.Tables(0)
For Each row As DataRow In dt.Rows
grabUserid = row("id")
Next
If dt.Rows.Count > 0 Then
FoundId = 1
Else
FoundId = 0
End If
Catch ex As Exception
'return error here
Finally
cn.Close()
End Try
'Assign the UserID Session
HttpContext.Current.Sessio n("Id") = grabUserid
If FoundId > 0 Then ' success
txtItems.Add(New WSLoginStatus("200"))
Else
txtItems.Add(New WSLoginStatus("400"))
End If
cn.Close()
'Serializing list:
Dim jss As New JavaScriptSerializer()
Dim jsonFlexBoxItems As New StringBuilder
jss.Serialize(txtItems, jsonFlexBoxItems)
HttpContext.Current.Respon se.Content Type = "application/json"
HttpContext.Current.Respon se.Charset = "utf-8"
Return txtItems.ToArray - WHJEN I RETURN THIS NO JSON IS DISPLAYED AT ALL BUT WHEN I COMMENT IT OUT AND RETURN THIS:
Return jsonFlexBoxItems.ToString - THEN A STRING JSON IS RETURNED BUT WITH THE "d" OBJECT AND ESCAPED CHARACTERS IN THE STRING.
End Function
I am also calling this via JQUERY POST:
<script type="text/javascript" src="../Scripts/jquery-1.4 .1.min.js" ></script>
<script src="../Scripts/jquery-1.4 .1.js" type="text/javascript"></s cript>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$('#target').click(functio n () {
$.ajax({
type: "POST",
url: "http://localhost:53001/MYSITE/opentgaterwfc.svc/LoginAuth",
data: '{"email":"email@email.com ", "password":"test123"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Hide the fake progress indicator graphic.
$('#RSSContent').removeCla ss('loadin g');
// Insert the returned HTML into the <div>.
$('#TextBox1').text(msg);
//$('#RSSContent').html(ms g.d);
}
});
});
});
</script>
Any Ideas?
<ServiceContract(Namespace
<AspNetCompatibilityRequir
Public Class openapiwfc
Dim ds As New DataSet
Dim dt As New DataTable
' To use HTTP GET, add <WebGet()> attribute. (Default ResponseFormat is WebMessageFormat.Json)
' To create an operation that returns XML,
' add <WebGet(ResponseFormat:=We
' and include the following line in the operation body:
' WebOperationContext.Curren
<OperationContract()> _
<WebInvoke(ResponseFormat:
<WebMethod(EnableSession:=
Public Function LoginAuth(ByVal email As String, ByVal password As String)
Dim txtItems As New List(Of Object)
'ADO.Net
Dim strCn As String = System.Configuration.Confi
'"data source=.;Initial Catalog=MyDB;Integrated Security=True"
Dim cn As New SqlClient.SqlConnection()
cn.ConnectionString = strCn
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = cn
cmd.CommandType = CommandType.Text
If email = "" Then
email = "none"
End If
If password = "" Then
password = "none"
End If
Dim grabUserid As String = ""
Dim FoundId As Integer
cmd.CommandText = "SELECT Id, Email, Password from tbluser WHERE Email=@Email AND Password=@Password AND UserActive ='Yes'"
cmd.Parameters.AddWithValu
cmd.Parameters.AddWithValu
Try
cn.Open()
cmd.ExecuteNonQuery()
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
dt = ds.Tables(0)
For Each row As DataRow In dt.Rows
grabUserid = row("id")
Next
If dt.Rows.Count > 0 Then
FoundId = 1
Else
FoundId = 0
End If
Catch ex As Exception
'return error here
Finally
cn.Close()
End Try
'Assign the UserID Session
HttpContext.Current.Sessio
If FoundId > 0 Then ' success
txtItems.Add(New WSLoginStatus("200"))
Else
txtItems.Add(New WSLoginStatus("400"))
End If
cn.Close()
'Serializing list:
Dim jss As New JavaScriptSerializer()
Dim jsonFlexBoxItems As New StringBuilder
jss.Serialize(txtItems, jsonFlexBoxItems)
HttpContext.Current.Respon
HttpContext.Current.Respon
Return txtItems.ToArray - WHJEN I RETURN THIS NO JSON IS DISPLAYED AT ALL BUT WHEN I COMMENT IT OUT AND RETURN THIS:
Return jsonFlexBoxItems.ToString - THEN A STRING JSON IS RETURNED BUT WITH THE "d" OBJECT AND ESCAPED CHARACTERS IN THE STRING.
End Function
I am also calling this via JQUERY POST:
<script type="text/javascript" src="../Scripts/jquery-1.4
<script src="../Scripts/jquery-1.4
<script language="javascript" type="text/javascript">
$(document).ready(function
$('#target').click(functio
$.ajax({
type: "POST",
url: "http://localhost:53001/MYSITE/opentgaterwfc.svc/LoginAuth",
data: '{"email":"email@email.com
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Hide the fake progress indicator graphic.
$('#RSSContent').removeCla
// Insert the returned HTML into the <div>.
$('#TextBox1').text(msg);
//$('#RSSContent').html(ms
}
});
});
});
</script>
Any Ideas?
[ServiceContract]
public interface ILoginService
{
[OperationContract]
[WebInvoke(Method="POST"ResponseFormat=WebMessageFormat.Json,UriTemplate="/RemoveKiosk/{userId}/{password}")]
public LoginStatus Login(string userName, string passWord)
{
}
}
public class LoginService : ILoginService
{
public LoginStatus Login(string userName, string passWord)
{
//Your login Authentication goes here
if(found>0)
return new LoginStatus("200");
else
return new LoginStatus("400");
}
}
Then from json you can call this url as:-
http://<yourServicePath>//LoginSe
ASKER
Ok thanks, is there any other way to make this work the way I'm trying to make it work? As I said I can return escaped strings fine if I serialize the list that I'm returning. All I'm trying to do now is return pure JSON.
ASKER
Ok basically I have found that returning any type of non object value (such as string) returns a response: {"d":"200"}
And when I try to return an object to eliminate the "d" from the response It doesn't work, nothing is being returned when I try to return an object.
And when I try to return an object to eliminate the "d" from the response It doesn't work, nothing is being returned when I try to return an object.
are you sure that your login status is a datacontract and d as datamember like this:-
this way when your return an instance of loginstatus type and specify your response format as json, it will be serialized to json string using javascriptserializer automatically/automagicall y.
[DataContract]
public class LoginStatus
{
[DataMember]
public string d{get;set;}
public LoginStatus(string value)
{
d=value;
}
}
this way when your return an instance of loginstatus type and specify your response format as json, it will be serialized to json string using javascriptserializer automatically/automagicall
ASKER
Ok I'm having trouble calling this form my code. This is what I have now (thanks to your help), now how do I add my "200" or "400" response codes so that they're returned?
Please, I'm also using VB.net and am very new to the new WCF approvach, so please bare with me.
<DataContract()> _
Public Class LoginStatus
Private LoginResponse As Integer
<DataMember()> _
Public Property d() As Integer
Get
Return LoginResponse
End Get
Set(ByVal value As Integer)
LoginResponse = value
End Set
End Property
End Class
Please, I'm also using VB.net and am very new to the new WCF approvach, so please bare with me.
<DataContract()> _
Public Class LoginStatus
Private LoginResponse As Integer
<DataMember()> _
Public Property d() As Integer
Get
Return LoginResponse
End Get
Set(ByVal value As Integer)
LoginResponse = value
End Set
End Property
End Class
Dim status As New LoginStatus() With { _
.LoginResponse = "200" _
}
Return status
ASKER
Ok thanks, now I'm back to getting a null error when I look at my firebug. If I use your sample URI code do I have to post from my JSON or do I have to perform GET?
Here is my Ajax code
$(document).ready(function () {
$('#target').click(functio n () {
$.ajax({
type: "POST",
url: "http://localhost:50635/MYSITE/opentgaterwcf.svc/LoginAuth/email@email.com/PassWord",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
}
});
});
});
And here is my WebInvoke and Function:
<OperationContract()> _
<WebInvoke(Method:="POST", ResponseFormat:=WebMessage Format.Jso n, UriTemplate:="/LoginAuth/{ userId}/{p assword}") > _
<WebMethod(EnableSession:= True)> _
Public Function LoginAuth(ByVal email As String, ByVal password As String) As Object
'Validation goes here
End Function
Here is my Ajax code
$(document).ready(function
$('#target').click(functio
$.ajax({
type: "POST",
url: "http://localhost:50635/MYSITE/opentgaterwcf.svc/LoginAuth/email@email.com/PassWord",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
}
});
});
});
And here is my WebInvoke and Function:
<OperationContract()> _
<WebInvoke(Method:="POST",
<WebMethod(EnableSession:=
Public Function LoginAuth(ByVal email As String, ByVal password As String) As Object
'Validation goes here
End Function
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Man... Thanks for your help but this is crazy complicated and will not work. I've gone over this stuff for 48 hours now. I'm just going to go back to asmx in the meantime in hopes that microsoft simplifies integration with WCF - what a mess! Thanks for your help though!
ASKER
<Serializable()> Public Class WSLoginStatus
Private _respCode As String
Public Property respCode As String
Get
Return _respCode
End Get
Set(ByVal value As String)
_respCode = value
End Set
End Property
Public Sub New(ByVal respCode As String)
Me._respCode = respCode
End Sub
End Class