Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

WCF Web Service return raw json

Posted on 2012-04-10
10
Medium Priority
?
1,693 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

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 2000 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
Introduction Since I wrote the original article about Handling Date and Time in PHP and MySQL several years ago, it seemed like now was a good time to update it for object-oriented PHP.  This article does that, replacing as much as possible the pr…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

610 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