Asked  7 Months ago    Answers:  5   Viewed   28 times

I'm working on a project using Symfony 2, I've built a bundle to handle all my database services which passes JSON data back and forward.

My Problem/Question:

  • Is it possible to post a straight up JSON object? Currently I'm spoofing a normal form post for my ajax calls by giving the object a name json={"key":"value"} if I don't give it a name I can't seem to get the data from the Symfony request object $JSON = $request->request->get('json');

  • I want to be able to use the one service bundle to handle both data coming from AJAX calls, or a normal Symfony form. Currently I'm taking the submitted Symfony form, getting the data then using JSON_ENCODE, I just can't work out how to post the data through to my services controller which is expecting request data.

To summarise:

  • I want Symfony to accept a JSON post object rather than a form.

  • I want to pass the JSON object between controllers using Request/Response

If I'm going about this all wrong, feel free to tell me so!

 Answers

46

If you want to retrieve data in your controller that's been sent as standard JSON in the request body, you can do something similar to the following:

public function yourAction()
{
    $params = array();
    $content = $this->get("request")->getContent();
    if (!empty($content))
    {
        $params = json_decode($content, true); // 2nd param to get as array
    }
}

Now $params will be an array full of your JSON data. Remove the true parameter value in the json_decode() call to get a stdClass object.

Wednesday, March 31, 2021
 
Grzegorz
answered 7 Months ago
33

Use sfAction::getPartial() and getComponent().

Wednesday, March 31, 2021
 
TheTechnicalPaladin
answered 7 Months ago
24

If what you're worried is the absence of contract, then maybe you should just write a unit test. It could go even further since you could also have a contract on the values of the attributes, this way.

Saturday, May 29, 2021
 
Sagar
answered 5 Months ago
30

Take a look at Phil Haack's post on model binding JSON data. The problem is that the default model binder doesn't serialize JSON properly. You need some sort of ValueProvider OR you could write a custom model binder:

using System.IO;
using System.Web.Script.Serialization;

public class JsonModelBinder : DefaultModelBinder {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
            if(!IsJSONRequest(controllerContext)) {
                return base.BindModel(controllerContext, bindingContext);
            }

            // Get the JSON data that's been posted
            var request = controllerContext.HttpContext.Request;
            //in some setups there is something that already reads the input stream if content type = 'application/json', so seek to the begining
            request.InputStream.Seek(0, SeekOrigin.Begin);
            var jsonStringData = new StreamReader(request.InputStream).ReadToEnd();

            // Use the built-in serializer to do the work for us
            return new JavaScriptSerializer()
                .Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);

            // -- REQUIRES .NET4
            // If you want to use the .NET4 version of this, change the target framework and uncomment the line below
            // and comment out the above return statement
            //return new JavaScriptSerializer().Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);
        }

        private static bool IsJSONRequest(ControllerContext controllerContext) {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            return contentType.Contains("application/json");
        }
    }

public static class JavaScriptSerializerExt {
        public static object Deserialize(this JavaScriptSerializer serializer, string input, Type objType) {
            var deserializerMethod = serializer.GetType().GetMethod("Deserialize", BindingFlags.NonPublic | BindingFlags.Static);

            // internal static method to do the work for us
            //Deserialize(this, input, null, this.RecursionLimit);

            return deserializerMethod.Invoke(serializer,
                new object[] { serializer, input, objType, serializer.RecursionLimit });
        }
    }

And tell MVC to use it in your Global.asax file:

ModelBinders.Binders.DefaultBinder = new JsonModelBinder();

Also, this code makes use of the content type = 'application/json' so make sure you set that in jquery like so:

$.ajax({
    dataType: "json",
    contentType: "application/json",            
    type: 'POST',
    url: '/Controller/Action',
    data: { 'items': JSON.stringify(lineItems), 'id': documentId }
});
Wednesday, June 9, 2021
 
Zigglzworth
answered 5 Months ago
70

after searching docs and trying out some codes I got following as an example

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];


NSDictionary *params = @ {@"user" :txtUserName, @"pwd" :txtPwd };


[manager POST:URL_SIGNIN parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
    NSLog(@"JSON: %@", responseObject);
}
failure:
 ^(AFHTTPRequestOperation *operation, NSError *error) {
     NSLog(@"Error: %@", error);
 }];

Also don't forget to set response header type in the server script as Application/json.

Saturday, June 12, 2021
 
Claudio
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share