Symfony3 deserialize multiple entity objects - serialization

Serialize and deserialize single entity object work properly for me.
It is possible to serialize and deserialize multiple object (array of objects) in this way??
$notifications = $this->getDoctrine()
->getRepository('AppBundle:Notification')
->findAll();
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer();
$serializer = new Serializer(array($normalizer), array($encoder));
$jsonContent = $serializer->serialize($notifications, 'json');
return new Response($jsonContent);
And
$response = curl_exec($ch); // my $jsonContent from previous code
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer();
$serializer = new Serializer(array($normalizer), array($encoder));
$notifications = $serializer->deserialize($response, Notification::class, 'json');
Then i got:
The property path constructor needs a string or an instance of
"Symfony\Component\PropertyAccess\PropertyPath". Got: "integer" 500
Internal Server Error - UnexpectedValueException

I found solution
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;
$serializer = new Serializer(
array(new GetSetMethodNormalizer(), new ArrayDenormalizer()),
array(new JsonEncoder())
);
$data = ...; // The serialized data from the previous example
$persons = $serializer->deserialize($data, 'Acme\Person[]', 'json');

Related

Simple serialize ODataQueryOptions

I'm trying to:
[EnableQuery]
[HttpGet]
[ODataRoute("")]
public IHttpActionResult Get(ODataQueryOptions<UserODataModel> options)
{
var users = _repository.RetrieveOData();
var serialQuery = JsonConvert.SerializeObject(options, jsonOptions);
//save serialQuery somewhere
return Ok(users);
}
But got
Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'ReadTimeout' on 'Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream'.'
"Timeouts are not supported on this stream."
I know there is already a question about serialize Stream:
Newtonsoft Json.net - how to serialize content of a stream?
But in this case i can't "extract stream value" from ODataQueryOptions, or can I?
Some ideia?
Since we work on the same company, if anyone is interested, we found a way, maybe not the pretty way, to serialize an ODataQueryOptions:
public static ODataQueryOptions DeserializeQueryOptions(SerializedQueryOptions options)
{
var uri = new Uri(teste.OriginalUri);
var model = ODataConfig.Model; //GetEdmModel
var segment = model.EntityContainer.FindEntitySet(options.EdmType);
var newPath = new Microsoft.AspNet.OData.Routing.ODataPath(new EntitySetSegment(segment));
var httpConfiguration = new HttpConfiguration();
httpConfiguration.EnableDependencyInjection();
var request = new HttpRequestMessage(HttpMethod.Get, uri)
{
Properties =
{
{ HttpPropertyKeys.HttpConfigurationKey, httpConfiguration },
}
};
var context = new ODataQueryContext(model, options.EntityType, newPath);
var oDataQueryOptions = new ODataQueryOptions(context, request);
return oDataQueryOptions;
}
public static SerializedQueryOptions SerializeQueryOptions(ODataQueryOptions options)
{
return new SerializedQueryOptions
{
OriginalUri = options.Request.RequestUri.AbsoluteUri,
EdmType = options.Context.NavigationSource.Name,
EntityType = options.Context.ElementClrType
};
}
After you serialize it to an object you can serialize it to a JSON string:
var queryOptionsSerialized = new SerializedQueryOptions()
{
OriginalUri = "http://localhost:25723/odata/users?$skip=0&$top=2&$orderby=fullName&$count=true",
EdmType = "users",
EntityType = typeof(UserODataModel)
};
var json = JsonConvert.SerializeObject(queryOptionsSerialized);
var deserialized = JsonConvert.DeserializeObject<SerializedQueryOptions>(json);
var options = ODataQueryOptionsHelper.DeserializeQueryOptions(deserialized);
In case One is not using OData routing or using an ApiController (not ODataController),
modify the way of Obtaining ODataPath to:
ODataUriParser parser = new ODataUriParser(model, serviceRoot, requestUri);
ODataPath path = parser.ParsePath();
//var newPath = new Microsoft.AspNet.OData.Routing.ODataPath(new EntitySetSegment(segment));
Microsoft.AspNet.OData.Routing.ODataPath newPath = new Microsoft.AspNet.OData.Routing.ODataPath(path.FirstOrDefault());
where the serviceRoot is the Url part other that the path defined in the model.

Report Viewer and Web Api

In MVC I could generate .xsl or .pdf file with no issues with File(), but with the web Api nothing is happening when the action is fired! This is what I have tried so far.
I have tried a couple of solutions in here including this one Web API and report viewer
but nothing has worked for me.
public HttpResponseMessage Export(ExportVolunteerSearchFilter searchModel)
{
if (searchModel.Equals(null))
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
var volunteers = _volunteersService.ExportAllVolunteersData(searchModel);
ReportViewer ReportViewer1 = new ReportViewer();
ReportViewer1.SizeToReportContent = true;
ReportViewer1.LocalReport.ReportPath =
System.Web.HttpContext.Current.Server.MapPath("~/Reports/VolunteersReport.rdlc");
ReportViewer1.LocalReport.EnableExternalImages = true;
ReportViewer1.LocalReport.DataSources.Clear();
ReportDataSource _rsource = new ReportDataSource("DataSet1", volunteers);
ReportViewer1.LocalReport.DataSources.Add(_rsource);
ReportViewer1.LocalReport.Refresh();
Warning[] warnings;
string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;
string fileName = "reportVolunteer";
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(System.Web.HttpContext.Current.Server.MapPath("~/Reports/VolunteersReport.rdlc"), FileMode.Open);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xls");
return response;
}
I have done it as:-
response.Content = new PushStreamContent(
async (outstream) =>
{
await getDataMethod(outstream)
},
new MediaTypeHeadrerValue(mediaType:"application/xls"));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = $"test.xls"
};
return response;

Converting a JSON object to an equivalent in JAVA

I am massively stuck with converting a PHP server request into an equivalent Java Request. This is the code that contains the JSON object that I need to replicate in JAVA and send from an Android device:
$(".unableprocess").click(function() {
if (!confirm("Confirm not able to process...!")) {
return false;
} else {
var item_id = $(this).attr('data-id');
var table_id = $(this).attr('table-id');
var data = {
BookOrders: {
item_id: item_id,
table_id: table_id
}
};
$.ajax({
url: //MY URL HERE ,
type: "POST",
data: data,
success: function(evt, responseText) {
location.reload();
}
});
}
});
And here is my Java class that attempts to perform the same functionality. The class extends AsyncTask and all network interactions occur in the doInBackground() method. Here is my code:
#Override
protected Boolean doInBackground(String... arg0) {
try{
HashMap<String, String> hashMap = new HashMap<String,String>();
JSONObject jsonObject = new JSONObject();
int statusCode;
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(tableMateCannotProcessURL);
// JSON object creation begins here:
jsonObject.accumulate("item_id",this.itemId);
jsonObject.accumulate("table_id",this.tableId);
JSONObject jObject = new JSONObject();
jObject.accumulate("BookOrders", jsonObject);
// JSON object ends here
Log.v("ATOMIC BLAST",jObject.toString());
String json = jObject.toString();
StringEntity se = new StringEntity(json);
httpPost.setEntity(se);
HttpResponse response = client.execute(httpPost);
statusCode = response.getStatusLine().getStatusCode();
Integer statusCodeInt = new Integer(statusCode);
Log.v("HTTPResponse",statusCodeInt.toString());
String result= "";
StringBuilder builder = new StringBuilder();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
result = builder.toString();
}
else {
Log.e("==>", "Failed to download file");
}
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
The JSON object that I created looks like this after printing it out to the console:
{"BookOrders":{"table_id":"1","item_id":"2"}}
After POSTing this object to the server I do not get the expected response. What is the proper method for converting the JSON object into an equivalent JSON object in JAVA? Any guidance, direction or a solution would be most appreciated.
Update php to version 5.4 helped me.
In this version json_encode($x, JSON_PRETTY_PRINT) works just as needed.
Your JSON seems to be correct but it's an Object in an Object.
JSONObject json = new JSONObject(yourdata);
JSONObject jsonTable = new JSONObject(json.getString("BookOrders"));
Log.d("JsonDebug", "json:" + jsonTable.toString());
If you are not sure if you have a JSONObject or an Array you can validate it by using
String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
//you have an object
else if (json instanceof JSONArray)
//you have an array

How to add test case when post a test case result

The JsonObject addProperty cannot support to add another JsonObject.
The official test shown on below:
#Test
public void shouldConstructTheCorrectUrlWithExtraParam() {
JsonObject body = new JsonObject();
CreateRequest req = new CreateRequest("Defect", body);
req.addParam("foo", "Bar");
Assert.assertEquals(req.toUrl(), "/defect/create.js?foo=Bar&fetch=true");
}
What I need is ???:
public void shouldConstructTheCorrectUrlWithExtraParam() {
JsonObject body = new JsonObject();
body.add("testcase",???)
CreateRequest req = new CreateRequest("testcaseresult", body);
req.addParam("foo", "Bar");
Assert.assertEquals(req.toUrl(), "/defect/create.js?foo=Bar&fetch=true");
}
I did a mistake for adding other JsonObject, it's a ref instead a instance.
Works well code:
public void createTestCaseResult(JsonObject testCaseJsonObject) throws IOException, URISyntaxException {
log.println("createTestCaseResult...");
String testCaseRef = testCaseJsonObject.get("_ref").getAsString();
QueryRequest userRequest = new QueryRequest("user");
userRequest.setFetch(new Fetch("UserName", "Subscription", "DisplayName"));
userRequest.setQueryFilter(new QueryFilter("UserName", "=", "lu.han#technicolor.com"));
QueryResponse userQueryResponse = restApi.query(userRequest);
JsonArray userQueryResults = userQueryResponse.getResults();
JsonElement userQueryElement = userQueryResults.get(0);
JsonObject userQueryObject = userQueryElement.getAsJsonObject();
String userRef = userQueryObject.get("_ref").getAsString();
close();
getRestApi();
Date now = new Date();
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
SimpleDateFormat format = new SimpleDateFormat(pattern);
JsonObject newResult = new JsonObject();
newResult.addProperty("Verdict", "Pass");
newResult.addProperty("Build", "2014.01.08.1234567");
newResult.addProperty("Tester", userRef);
newResult.addProperty("Date", format.format(now));
newResult.addProperty("CreationDate", format.format(now));
newResult.addProperty("TestCase", testCaseRef);
newResult.addProperty("Workspace", workspaceRef);
CreateRequest createRequest = new CreateRequest("testcaseresult", newResult);
CreateResponse createResponse = restApi.create(createRequest);
log.println("createTestCaseResult DONEļ¼š");
log.println(String.format("Created %s", createResponse.getObject().get("_ref").getAsString()));
}

JSON.Net serialize XML to JSON camel case

How do I get JSON.Net to serialize my XML to camel case JSON and without the "#"?
this is what I currently have but it prepends # to the properties and does not camel case...
XmlDocument doc = new XmlDocument();
doc.LoadXml(myXmlString);
string jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(doc, new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
Make a model of your XML data
example
public class MyClass
{
[JsonProperty("#SomeXMLProperty")]
public string MyString{ get; set; }
}
then deserialize XML to your model
XDocument xmlDocument = XDocument.Parse(xmlData);
string jsonData = JsonConvert.SerializeXNode(xmlDocument);
var myClass = JsonConvert.DeserializeObject<MyClass>(jsonData);
then just use CamelCasePropertyNamesContractResolver and Formatting.Indented
string json = JsonConvert.SerializeObject(rootObject,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
UPDATE:
The first solution is simple and clean (no need to write custom resolvers etc.) this is just for removing # sign
var xml = new XmlDocument();
xml.XmlResolver = null;
xml.Load("yourfilehere");
var json = JsonConvert.SerializeXmlNode(xml, Newtonsoft.Json.Formatting.Indented);
var withoutATSign = System.Text.RegularExpressions.Regex.Replace(json, "(?<=\")(#)(?!.*\":\\s )", String.Empty, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
If anybody knows a better solution for both cases then the first it would be nice to look at it.
WebAPI addition
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();