Solved

WCF Web Service return raw json

Posted on 2012-04-10
10
1,625 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
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

 

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
 

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
asp.net web application 3 46
Dictionary and array of [N] size - performance tuned 12 42
ASP.NET Built-In Report Creator / Viewer 5 25
Web page design problem 3 19
Preface In the first article: A Better Website Login System (http://www.experts-exchange.com/A_2902.html) I introduced the EE Collaborative Login System and its intended purpose. In this article I will discuss some of the design consideratio…
I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

730 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