6

I'm starting to learn Json.NET, but I'm having trouble using its serializer. I have a new MVC4 project with a Web.API service:

public class PTE_TestsController : ApiController {

  PTE_TestsRepository _repository = new PTE_TestsRepository();

  // GET /api/PTE_Tests/5
  public HttpResponseMessage<string> Get(int id) {
    try {
       PTE_Test test = _repository.GetTest(id);
       return new HttpResponseMessage<string>(JsonConvert.SerializeObject(test));
    } catch {
       return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
    }
  }
}

JsonConvert.SerializeObject() works as expected and returns a string. My Web.API controller returns that as part of an HttpResponseMessage. The end result, when viewed in Fiddler, is not JSON data, but JSON data being serialized again (I think):

"{\"ID\":1,\"Name\":\"Talar Tilt\",\"TagID\":1,\"PracticeID\":1,
   \"SpecificAreaID\":1,\"TypeID\":1,\"VideoID\":1,\"PicID\":1}"

Does someone know how to turn off the default serializer so I can use Json.NET directly? By the way, I'm not using the default serializer because I can't figure out how to make it work with complex objects (PTE_Test will eventually contain members of type List).

Alternately, it will also solve my problem if someone can explain how to use the default serializer with complex objects. MSDN's explanation didn't help me.

3 Answers 3

5

Rick Strahl has a blog on that here with a code that works.

Sign up to request clarification or add additional context in comments.

2 Comments

His tip on using a JsonValue object was exactly what I needed. Thanks!
Quick follow-up: JsonValue only worked for me on Get, but not Put, Post, etc. So I added Rick's Json.NET formatter and so far it's working quite nicely.
2

As others have pointed out, you need to create a formatter and replace the DataContractSerializer with the JSON.NET serializer. Although, if you're not in a rush for JSON.NET specifically, rumor has it that next beta/rc is going to have support for JSON.NET built in.

Conceptually, however, you're missing part of the magic of WebAPI. With WebAPI you return your object in it's native state (or IQueryable if you want OData support). After your function call finishes the Formatter's take over and convert it into the proper shape based on the client request.

So in your original code, you converted PTE_Test into a JSON string and returned it, at which point the JSON Formatter kicked in and serialized the string. I modified your code as follows:

  public class PTE_TestsController : ApiController {
    PTE_TestsRepository _repository = new PTE_TestsRepository();

    public HttpResponseMessage<PTE_Test> Get(int id)  {
        try {
            PTE_Test test = _repository.GetTest(id);
            return new HttpResponseMessage(test);
        } catch {
            return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
        }
     }
   }

Notice how your function returns PTE_Test instead of string. Assuming the request came in with a request header of Accept = application/json then the JSON formatter will be invoked. If the request had a header of : Accept = text/xml the XML formatter is invoked.

There's a decent article on the topic here. If you're a visual learner, Scott Gu shows some examples using fiddler in this video, starting around 37 minutes. Pedro Reys digs a little deeper into content negotiation here.

2 Comments

Thanks for the detailed answer. I understand conceptually why it would be nice to have my own formatter. I also see now why it could be useful in our project. I'm not sure how to add it to my code, but I'll watch the ScottGu video and follow up here if I have any more questions.
Note, that if you can get by with the current JSON serlializer, in the next release JSON.NET will be one of the built in serializer.
0

The way to do this is to use formatters.

Check out: https://github.com/WebApiContrib/WebAPIContrib/tree/master/src/WebApiContrib.Formatting.JsonNet.

Json.NET support will be in the RC release of Web API.

1 Comment

Thanks for the quick response! I ended up using JsonValue instead, but the formatters are good to know about.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.