Link to home
Start Free TrialLog in
Avatar of jtmerch
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:="loginwebsvc")>
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.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:=WebMessageFormat.Xml)>,
    '     and include the following line in the operation body:
    '         WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml"
    <OperationContract()> _
       <WebInvoke(ResponseFormat:=WebMessageFormat.Json)> _
    <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.ConfigurationManager.AppSettings("ConnectDB")
        '"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.AddWithValue("@Email", email)
        cmd.Parameters.AddWithValue("@Password", Encryption.Encrypt(password))

        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.Session("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.Response.ContentType = "application/json"
        HttpContext.Current.Response.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"></script>


    <script language="javascript" type="text/javascript">

        $(document).ready(function () {
            $('#target').click(function () {
                $.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').removeClass('loading');

                        // Insert the returned HTML into the <div>.
                        $('#TextBox1').text(msg);
                       //$('#RSSContent').html(msg.d);

                    }
                });
            });
            });
 

</script>


Any Ideas?
Avatar of jtmerch
jtmerch

ASKER

Also, the WSLoginStatus class that I'm calling in the above code is simply this:


<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
[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");
}
}

Open in new window


Then from json you can call this url as:-

http://<yourServicePath>//LoginService.svc/Login/MyUser/MyPassword;
Avatar of jtmerch

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.
Avatar of jtmerch

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.
are you sure that your login status is a datacontract and d as datamember like this:-

[DataContract]
public class LoginStatus
{
[DataMember]
public string d{get;set;}

public LoginStatus(string value)
{
d=value;
}

}

Open in new window


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/automagically.
Avatar of jtmerch

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
Dim status As New LoginStatus() With { _
	.LoginResponse = "200" _
}
Return status

Open in new window

Avatar of jtmerch

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(function () {
                $.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:=WebMessageFormat.Json, UriTemplate:="/LoginAuth/{userId}/{password}")> _
     <WebMethod(EnableSession:=True)> _
    Public Function LoginAuth(ByVal email As String, ByVal password As String) As Object
'Validation goes here
End Function
ASKER CERTIFIED SOLUTION
Avatar of BuggyCoder
BuggyCoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jtmerch

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!