Solved

WCF Web Service return raw json

Posted on 2012-04-10
10
1,599 Views
Last Modified: 2012-04-14
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?
0
Comment
Question by:jtmerch
  • 6
  • 4
10 Comments
 

Author Comment

by:jtmerch
ID: 37831289
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
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37831338
[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;
0
 

Author Comment

by:jtmerch
ID: 37833171
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.
0
 

Author Comment

by:jtmerch
ID: 37834259
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.
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37834348
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.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:jtmerch
ID: 37834517
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
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37834535
Dim status As New LoginStatus() With { _
	.LoginResponse = "200" _
}
Return status

Open in new window

0
 

Author Comment

by:jtmerch
ID: 37834679
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
0
 
LVL 20

Accepted Solution

by:
BuggyCoder earned 500 total points
ID: 37834703
Use This:-
Public Function LoginAuth(ByVal email As String, ByVal password As String) As LoginStatus

Open in new window


Also suggest you download fiddler and generate a post request from there to your webservice and see what happens there.

Make sure you have done the endpoint configuration right in web config, here is how to do it for restful service:-
http://msdn.microsoft.com/en-us/magazine/dd315413.aspx
0
 

Author Comment

by:jtmerch
ID: 37834767
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!
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

What is Node.js? Node.js is a server side scripting language much like PHP or ASP but is used to implement the complete package of HTTP webserver and application framework. The difference is that Node.js’s execution engine is asynchronous and event…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to count occurrences of each item in an array.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now