3

I'm trying to create a JSON object that can be read as a C# object, and when I try to send it via AJAX, I keep getting 400 bad request errors.

My JavaScript is as follows:

$.ajax({
type: "POST",
url: "LeagueService.svc/Fixtures",
    data: JSON.stringify(fixture),
    dataType: "json",
    contentType: "application/json",
    success: function (json, status, req) {
        $successMessage = '<div class="hero-unit"><h2>Success</h2><p>The fixture has been added to the database.</p></div>';

        $('#dialog').html($successMessage).fadeOut(500, function (e) {
            $(this).dialog("close");
        });

     },
     error: function (req, status, error) {
       alert('Error: ' + req.responseText);
     }
});

And my Fixture object looks like:

function Fixture() { }

Fixture.prototype =
{
    ID: "",
    HomeTeam: "",
    AwayTeam: "",
    Date: "",

    toJSON: function () { return { "fixture": {"ID" : this.ID, "HomeTeam" : this.HomeTeam, "AwayTeam" : this.AwayTeam, "Date" : this.Date} }; }
};

This approach has worked absolutely fine in other functions I have written, so I am not sure what is going wrong now.

My C# method and interface: Interface:

[OperationContract]
[WebInvoke(Method = "POST",
    BodyStyle = WebMessageBodyStyle.Wrapped,
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    UriTemplate = "/Fixtures")]
void AddFixture(Fixture fixture);

And the method:

public void AddFixture(Fixture fixture)
{
    using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.DBConnect))
    {
        try
        {
            conn.Open();
            string query = "INSERT INTO tbFixtures (HomeTeam, AwayTeam, Date) VALUES(@HT, @AT, @Date);";
            using (SqlCommand cmd = new SqlCommand(query, conn))
            {
                cmd.Parameters.AddWithValue("@HT", fixture.HomeTeam.ID);
                cmd.Parameters.AddWithValue("@AT", fixture.AwayTeam.ID);
                cmd.Parameters.AddWithValue("@Date", fixture.Date);

                cmd.ExecuteNonQuery();
            }
        }
        catch (Exception) { }
        finally
        {
            conn.Close();
        }
    }
}

And the C# classes:

[DataContract(Name="Fixture", Namespace="")]
public class Fixture
{
    [DataMember(Name = "ID", Order = 1)]
    public int ID { get; set; }

    [DataMember(Name = "HomeTeam", Order = 2)]
    public Team HomeTeam { get; set; }

    [DataMember(Name = "AwayTeam", Order = 3)]
    public Team AwayTeam { get; set; }

    [DataMember(Name = "Date", Order = 4)]
    public DateTime Date { get; set; }
}

[DataContract(Name = "Team", Namespace = "")]
public class Team
{
    [DataMember(Name = "ID", Order = 1)]
    public int ID { get; set; }

    [DataMember(Name = "Name", Order = 2)]
    public string Name { get; set; }

    [DataMember(Name = "Wins", Order = 3)]
    public int Wins { get; set; }

    [DataMember(Name = "Losses", Order = 4)]
    public int Losses { get; set; }

    [DataMember(Name = "Draws", Order = 5)]
    public int Draws { get; set; }

    [DataMember(Name = "GoalsConceded", Order = 6)]
    public int GoalsConceded { get; set; }

    [DataMember(Name = "GoalsScored", Order = 7)]
    public int GoalsScored { get; set; }

    [DataMember(Name = "Manager", Order = 8)]
    public Manager Manager { get; set; }
}

[DataContract(Name = "Manager", Namespace = "")]
public class Manager
{
    [DataMember(Name = "ID", Order = 1)]
    public int ID { get; set; }
    [DataMember(Name = "Name", Order = 2)]
    public string Name { get; set; }
}

The Manager and Team class are written in exactly the same way as the Fixture class in the JavaScript.

The object serialises into what I thought was the right JSON, but obviously not if I'm getting these errors. The JSON produced is as follows:

{ "fixture": {
    "ID":0,
    "HomeTeam":{
        "ID":1,
        "Name":"Rhondda St FC",
        "Wins":21,
        "Losses":2,
        "Draws":4,
        "GoalsConceded":20,
        "GoalsScored":36,
        "Manager": {
            "ID":1,
            "Name":"Ron Burgundy"
        }
    },
    "AwayTeam": {
        "ID":2,
        "Name":"Mt Pleasant United FC",
        "Wins":18,
        "Losses":5,
        "Draws":3,
        "GoalsConceded":22,
        "GoalsScored":28,
        "Manager": { 
            "ID":2,
            "Name":"Brian Fantana"
        }
    },
    "Date":"02/19/2013 12:00pm"
}} 

If anybody could shed any light on this it would be greatly appreciated. Thanks!

Edit: The complete error (Without the CSS) is:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Request Error</title>
   </head>
  <body>
    <div id="content">
      <p class="heading1">Request Error</p>
      <p xmlns="">The server encountered an error processing the request. Please see the <a rel="help-page" href="http://localhost:55310/LeagueService.svc/help">service help page</a> for constructing valid requests to the service.</p>
    </div>
  </body>
</html>
jrdn
  • 819
  • 2
  • 10
  • 21
  • What is the complete error message? – jrummell Feb 25 '13 at 13:18
  • Added the error message to the end. – jrdn Feb 25 '13 at 13:27
  • Have you tried debugging your service method? – jrummell Feb 25 '13 at 13:29
  • I've found that the request doesn't ever reach the method, which leads me to believe that the service itself is not the problem – jrdn Feb 25 '13 at 13:35
  • 1
    Can you enable tracing at the server to see why the service is considering the request to be bad? Also, did you see the help page (as suggested in the error page) to compare with your request? – carlosfigueira Feb 25 '13 at 14:55
  • I'm not sure how to do that - simply running an ASP.NET project in VS2012. I looked at the help page, nothing really useful there - just a list of services. – jrdn Feb 25 '13 at 16:25
  • This is WCF right? Enabling tracing for your service should help tracking down the error, take at look at [this answer](http://stackoverflow.com/a/4271597/265261) for a how-to. – aknuds1 Feb 25 '13 at 18:23

1 Answers1

2

I think it's because it doesn't like the format of your date - i.e. '02/19/2013 12:00pm'. Try changing the type of Date in your C# Fixture Data Contract to be a string or editing the toJSON method of your JS Fixture prototype to return a string in a format such as "2013-02-19Z".

Polly Shaw
  • 2,932
  • 1
  • 15
  • 21
  • I tried changing the date, and that didn't work. Ultimately, I just changed the Fixture C# class to hold Team ID's instead of team objects, and it's working now. Not really what I wanted to do, but it works. – jrdn Feb 27 '13 at 15:03