views:

63

answers:

2

My app has a "Show all comments" similar to the one in Facebook. When the user clicks on the "show all" link, I need to update my list which initially has upto 4 comments with all comments. I'll show some code first and then ask some questions:

jQuery:
ShowAllComments = function (threadId) {
    $.ajax({
        type: "POST",
        url: "/Home/GetComments",
        data: { 'threadId': threadId },
        dataType: "json",
        success: function (result) {
            alert(result);
        },
        error: function (error) {
            alert(error);
        }
    });
};

Home Controller:
 // GET: /GetComments
 [HttpPost]
 public JsonResult GetComments(int threadId)
 {
     var comments = repository.GetComments(threadId).ToList();
      return Json(comments );
 }

Questions:

  1. When I tried GET instead of POST, I got this error: "This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet." Is POST usually recommended instead of GET when making these ajax requests? If not, how do I get it to work with GET? Where do I set JsonRequestBehavior to AllowGet?

  2. After changing it to POST, I now get this error: A circular reference was detected while serializing an object of type 'Models.Thread'. I'm using Entity Framework 4, and I've read that adding a [scriptignore] attribute on the navigation property would resolve this, so I added a partial class of the entity with the property, it said "property is already defined". How do I then deal with this because I can't directly modify the code generated by EF4.

+2  A: 
  1. Set in the return Json. I would just use post, but if you want to make it hard on your self, use get.

    public JsonResult blah() { return Json("obj", JsonRequestBehavior.AllowGet); }

  2. It is true when most ORM objects get serialized the serialization tries to searlize the hidden goodies the ORM needs, AND (sounds like your case) all of the lazy load stuff... this causes bad mojo. Can I throw a suggestion out? Why not let MVC do what its good at and generate the view for you? You could just use the jQuery .load and use a view.

CrazyDart
So you mean instead of manipulating the DOM myself with the json result, just call the action method through .load to get the AJAX effect?
Prabhu
that is correct!! $("#resultdiv").load(url, { 'threadId': threadId }); should work out for you.
CrazyDart
I was thinking and this is another good reason for MVVC... View Models. You should have a simple View Model that just shows what you need put in the view or in this case return as a JSON object. Check out this post: http://stackoverflow.com/questions/657939/serialize-entity-framework-objects-into-json
CrazyDart
Ok, I will stop after this one... surly I have better things to do... For SEO reasons you could drop the threadId, and just use the routed url. So localhost/Comments/ShowAllFor/2345345 would be a much better thing if you want SEO to have a good day.
CrazyDart
Thanks for the suggestions...will give these a try
Prabhu
A: 

Answers:

  1. try return Json(comments, JsonRequestBehavior.AllowGet); There are good reasons for the default behavior though.
  2. for anything going down the wire, you are going to really want to create a very simple view model object rather than sending your domain entity down the wire. Lots of fancy things happen in the EntityFramework that don't work with serialization as you are finding out.
Wyatt Barnett
So what's the logic behind this? Why doesn't the default setup allow me to do a GET?
Prabhu