Web API post array of objects? - javascript

I have an object as follows which is then stored in an array of them.
I would like to send the array of them to Web API, usually you would use JSON.stringify on an object, but would this work also being in an array?
I then need to work out what type of object they would be received as the other end as I need to iterate through them. I was hoping to use a typeof class.
var fieldarray = [];
$("div[class*=container_]").each(function (index) {
var firstElement = $(this).first();
var object = $(this).find('.object');
fielddata = {
id: firstElement.attr('class').match(/\d+/)[0],
attributes: [{
'label_text': firstElement.text(),
'label_width': firstElement.width(),
'label_height': firstElement.height(),
'label_color': firstElement.css('color'),
'Field_Width': object.width(),
'Field_Height': object.height,
'Field_Type': object.attr('Field_Type'),
'PositionX': firstElement.offset().left,
'PositionY': firstElement.offset().top,
'Field': firstElement.attr('class').match(/\d+/)[0],
'Label_Font': firstElement.css('font-family')
}]
}
array.push(fielddata);
});
Can I send this using JSON.stringify, and if so, what type would I receive this as in the Web API server side?
I usually use a public class type but the above code has an object inside an object - that is my problem.

I have sorted this now, basically I used:
[HttpPut]
public int Put(int id, [FromBody] FormData HTMLFORM)
{
....
}
and stored it in my type class as a string:
public class FormData
{
public int id { get; set; }
public string HTML { get; set; }
public string fieldData { get; set; }
}
I then used
IList<AttributeData> findingList = JsonConvert.DeserializeObject<IList<AttributeData>>(HTMLFORM.fieldData);
And it was stored in the list which I can iterate through using my type class of AttributeData!
Thanks

Related

Can you read connection strings from function bindings?

Can we bind to connection string value in order to simply output-bind to a specific storage account?
I would like to create a blob mover, where the consumer would pass an object like:
{
"sourceConnection":"..blob connection string",
"destinationConnection":"...blob connection string",
"filename":"/someContainer/someDir/myfile.jpg"
}
The function would be trigger by a queue:
{
"name": "myQueueItem",
"queueName": "myqueue-items",
"connection":"",
"type": "queueTrigger",
"direction": "in"
}
...where myQueueItem would have the payload as above.
How do we move a blob from sourceConnection to destinationConnection?
I'm specifying both the javascript as well as c# tags, because I need to make a solution in either one.
If we assumed that the source as well as destination storage accounts were the same, we could simply write a function to move blobs between two containers like so:
public static class BlobMover
{
[StorageAccount("Connection")]
[FunctionName("BlobMover")]
public static async Task Run(
[QueueTrigger("%BlobMover:TriggerQueue%")] BlobMessage msg,
[Blob("{source}-error/{name}", FileAccess.Write)] CloudBlockBlob error,
[Blob("{destination}/{name}", FileAccess.Write)] CloudBlockBlob #out,
[Blob("{source}/{name}", FileAccess.Read)] CloudBlockBlob #in,
ILogger log)
{
await #out.StartCopyAsync(#in);
}
}
However, the storage accounts are going to be different, so the solution above would not work.
Let’s assume you receive a payload input using a HTTP Triggered Azure function:
public class Payload
{
public string SourceContainer { get; set; }
public string DestinationContainer { get; set; }
public string SourceConnection{ get; set; }
public string DestinationConnection{ get; set; }
}
Now receive the information from the request:
var payload = req.Content.ReadAsAsync<Payload>();
var sourceConnection = payload.SourceConnection;
var destConnection = payload.DestinationConnection;
var sourceContainer = payload.SourceContainer;
var destContainer= payload.DestinationContainer;
Create the sourceClient and destinationClient:
#SOURCE
CloudStorageAccount sourceAccount = CloudStorageAccount.Parse(sourceConnection);
CloudBlobClient sourceClient = sourceAccount.CreateCloudBlobClient();
#DEST
CloudStorageAccount destAccount = CloudStorageAccount.Parse(destConnection);
CloudBlobClient destClient = destAccount .CreateCloudBlobClient();
Downloading from source
CloudBlobContainer sourceBlobContainer = sourceClient.GetContainerReference(sourceContainer);
ICloudBlob sourceBlob = await sourceBlobContainer.GetBlobReferenceFromServerAsync("MyBlob.doc");
await sourceBlob.DownloadToFileAsync("MyFile.doc", FileMode.Create);
Uploading to the destination
CloudBlobContainer destBlobContainer = destClient.GetContainerReference(destContainer);
CloudBlockBlob destBlob = destBlobContainer.GetBlockBlobReference("NewBlob.doc");
await destBlob.UploadFromFileAsync("MyFile.doc");

How to use JSON result in selenium webdriver

Im a beginner for automation testing.Here I want to get the data's from json to be used by selenium webdriver.I wrote one java class and hard coded something to get a result as a try.and getting an answer in console panel like
{
"name": "john",
"location": "jihu",
"job": [
{
"manager": [
{
"collegues": [
"ram",
"ranma",
],
}
}
}
(not exactly this).
Now i want to use this for one specific application using selenium webdriver. How can i move on with this.help me in detail.Thanks in advance.
From Selenium and Backend Comparison testing point of view i am answering the same .you need to parse json response using some Libraries like GSON , jackson etc into Java Pojo objects and then apply asserts on the fields you want to compare with json and UI. I guess you need to go through below topics first
1) Serialization -Deserialization API response
2) GSON or Jackson parsers
3) RestAssured ( Provides framework for API testing )
4) JAVA pojo classed and usage of them . you might need them to save your response in form of some Response class and compare objects .
You can use these online converters for converting a json object into Java Pojo Classes :
http://json2java.azurewebsites.net/ (I usually use this)
https://codebeautify.org/json-to-java-converter
and then place them in a package or in the same class as you wish :
You can better understand it by below example :
package com.demo.core;
import com.google.gson.Gson;
import io.restassured.RestAssured;
import io.restassured.response.Response;
public class Demo {
public static void main(String r[]) {
Response response1 = RestAssured.given().get("http://dummy.restapiexample.com/api/v1/employee/1"); // use your method to get the API response (I have used RestAssured here)
String json = response1.asString(); // you can use your json response here and convert it into a String
Gson gson = new Gson();
Employee emp = gson.fromJson(json, Employee.class); // The response is now captured in this Employee class
System.out.println(emp.getEmployeeAge());
System.out.println(emp.getEmployeeName());
System.out.println(emp.getEmployeeSalary());
}
}
class Employee {
private String id;
private String employee_name;
private String employee_salary;
private String employee_age;
private String profile_image;
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getEmployeeName() {
return this.employee_name;
}
public void setEmployeeName(String employee_name) {
this.employee_name = employee_name;
}
public String getEmployeeSalary() {
return this.employee_salary;
}
public void setEmployeeSalary(String employee_salary) {
this.employee_salary = employee_salary;
}
public String getEmployeeAge() {
return this.employee_age;
}
public void setEmployeeAge(String employee_age) {
this.employee_age = employee_age;
}
public String getProfileImage() {
return this.profile_image;
}
public void setProfileImage(String profile_image) {
this.profile_image = profile_image;
}
}
You can easily assert the values after the response is captured in Java classes using their getter methods like I have used in the code to get field values present in Employee class.
Please do let me know if you still got an issue.
If your result contains many fields than better to shift all converted java classes into a separate package for a clear code.

How to create a javascript model to send to an MVC controller?

I have a website served from a proprietary C++ server.
There is a standard javascript ajax function in the code but I don't want to start editing it.
The actual sending bit is as follows:
this.send=function(myawesomemodel)
{
/*Code redacted for brevity*/
obj.req.open('POST',myawesomeurl,true);
obj.req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
obj.req.send(JSON.stringify(myawesomemodel));
}
It used to send key value pairs as a query string but now it needs to send json.
I can send this function a controller/action address (myawesomeurl) for the appropriate end point and I can send it an awesome object which will be accepted by the action as a basic C# Model (myawesomemodel):
public ActionResult myawesomeaction(MyAwesomeClass myawesomeclass)
{
}
For the .Net model:
public class MyAwesomeClass
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
How do I build a javascript object the controller will recognise please?
Here's my latest failure:
function MyAwesomeModel()
{
this.A=1;
this.B=2;
this.C='Three';
}
Then:
var anawesomemodel=new MyAwesomeModel();
myawesomeajaxmodel.send(anawesomemodel);
I cannot construct the correct object in plain javascript so the mvc action registers it, what's the correct method please?
var myawesomemodel = {
A : 1,
B : 2,
C : 'Three'
}
For anyone else with the same problem who finds this page, Stephen Muecke nailed it
Change the ajax object to:
this.send=function(myawesomemodel)
{
/*Code redacted for brevity*/
obj.req.open('POST',myawesomeurl,true);
obj.req.setRequestHeader('Content-type','application/json;charset=utf-8');
obj.req.send(JSON.stringify(myawesomemodel));
}

Reading NewtonSoft Json Data with Jquery/Javascript

I am facing problem while using the object that i have sent from my controller to view using Json.
I am sending List of Objects to the View by using NewtonSoft.Json 7.x.x to serialize the List to Json. I am using the below code to serialize:
return JsonConvert.SerializeObject(DataToSend, Formatting.None, new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
I have 2 Entity Classes:
1) Form
2) FormFields
There is a 1-to-Many Relationship between these 2 entities.
public class Form
{
public long ID { get; set; }
public string Name { get; set; }
public virtual List<FormField> FormFields { get; set; }
}
public class FormField
{
public long FormID { get; set; }
public string FieldLabel { get; set; }
public string FieldType { get; set; }
public string FieldValue { get; set; }
public virtual Form form { get; set; }
}
I am trying to send the List of FormField to the view for rendering using Javascript. I am able to send it using the above serializaton Method.
But the problem is that, When i receive the Array of Objects in Javascript. It has Json Reference object IDs. I am not able to access those objects normally.
I am able to render the 1st FormField value in that array but i am not able to render rest of them. It is coming as Undefined.
I am attaching a screenshot of JSON Object Values which i am receiving on UI. You can see that there is an Object array. Each Object should have the Object of Type FormField and should have that field's value but there isn't.
Only the Object at index 0 is having the values and Rest of the Indexes have only Reference IDs.
Please help me resolve it.
Thanks
I don't know, if it is the best solution or not but I am posting so that may be it can save someone else's struggle to find the solution.
I Managed to do it using the .NET extension library plugin. Instead of using Newtonsoft.Json, I used System.Web.Extension DLL.
I put the attribute ScriptIgnore in my models as:
public class Form
{
public long ID { get; set; }
public string Name { get; set; }
[ScriptIgnore]
public virtual List<FormField> FormFields { get; set; }
}
public class FormField
{
public long FormID { get; set; }
public string FieldLabel { get; set; }
public string FieldType { get; set; }
public string FieldValue { get; set; }
[ScriptIgnore]
public virtual Form form { get; set; }
}
Then, I serialized it with the System.Web.Script.Serialization.JavaScriptSerializer as:
return new JavaScriptSerializer().Serialize(DataToSend);
It will serialize all the data but it will ignore the Properties which are having the attribute ScriptIgnore and it won't try to serialize them. For me it worked as required.
Just came to know that there is an Attribute JsonIgnore provided by NewtonSoft.Json that does the same job as ScriptIgnore. So, If you are using NewtonSoft Library then you can also use this.
It's good to know there are more ways to achieve the same result ;)

creating/updating breeze entities with one-to-one relationship

I'm working on a project using Breeze and I came across a problem with some entities I had created using a one-to-one relationship. This is a bit of a long story, but it has a happy ending, so bear with me :)
Here is a cut down version my C# code:
public class Person {
[Key]
public int Id { get; set; }
public virtual User User { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class User {
[Key]
public int Id { get; set; }
[Required]
public virtual Person Person { get; set; }
[Required]
public string EmailAddress { get; set; }
[Required]
public string Password { get; set; }
}
public class MyDbContext : DbContext {
public DbSet<Person> Person { get; set; }
public DbSet<User> User { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<User>().HasRequired(x => x.Person);
}
}
This creates a Persons database table with an auto generated primary key, and a Users table with a manually entered primary key, which is a subset of the Persons table.
I create these entities, and attempt to save them in my javascript code with something like:
var manager = new breeze.EntityManager('api/Db');
// other breeze initialization stuff, metadata etc.
var person=manager.createEntity('Person', undefined, breeze.EntityState.Detached);
var user=manager.createEntity('User', undefined, breeze.EntityState.Detached);
// set other fields, name, email, password
user.Person(user);
manager.addEntity(user);
manager.saveChanges().then(function() { // etc
When the SaveChanges function is called in my BreezeController I get this exception:
Validation error: Property: 'Person', Error: 'The Person field is required.'
Upon examination of the JSON that is send to the BreezeController I find that the Id of both the Person and the User was '-1', and that the JSON did not nest the Person entity inside the Person property of the User. So there was no way for the EFContextProvider to know that there was supposed to be a relationship between these objects.
My first attempt to solve this was to send the 'Person' entity to the backend with saveChanges, then send the 'User' in a seperate transaction. Eg:
manager.addEntity(person);
manager.saveChanges().then(function() {
user.Person(user); // this line moved from previous example,
// breeze throws error here
manager.addEntity(user);
manager.saveChanges().then(function() { // etc
Using this approach I got this error from breeze.js:
Cannot attach an object to an EntityManager without first setting its key
or setting its entityType 'AutoGeneratedKeyType' property to something other
than 'None' at checkEntityKey (http://localhost:12151/scripts/breeze.debug.js)
So I tried to set the key on the User to be the value filled in when the Person was saved. Using "user.Id(person.Id);" Now in the BreezeController I still get the same error:
Validation error: Property: 'Person', Error: 'The Person field is required.'
Next I tried to modify the SaveChanges method of my BreezeController to check for an incoming 'User' object which doesn't have a 'Person' property set, then Find the person in the database, and assign it to the Person before calling _efContextProvider.SaveChanges(saveBundle); I lost the code for exactly how I did this, but it's irrelevant as it didn't work properly either... It created a SECOND 'Person' in the database, exactly the same as the one that was saved in the first manager.saveChanges, but it had a new primary key generated. This did however successfully associate the second Person with the User.
After thinking about it overnight I came up with a working solution by subclassing the EFContextProvider with this:
public class MyEfContextProvider : EFContextProvider<MyDbContext>
{
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(
Dictionary<Type, List<EntityInfo>> saveMap)
{
AssociateOneToOne(saveMap, typeof(Person), typeof(User));
return saveMap;
}
private static void AssociateOneToOne(IReadOnlyDictionary<Type,
List<EntityInfo>> saveMap, Type parent, Type child)
{
if (!(saveMap.ContainsKey(parent) && saveMap.ContainsKey(child))) return;
Func<EntityInfo, object> idFunc = delegate(EntityInfo info)
{
var o = info.Entity;
return o.GetType().GetProperty("Id").GetValue(o);
};
var childProp = child.GetProperty(parent.Name);
var childMap = saveMap[child].ToDictionary(idFunc, info => info.Entity);
var parentMap = saveMap[parent].ToDictionary(idFunc, info => info.Entity);
foreach (var childEntry in childMap)
{
childProp.SetValue(childEntry.Value, parentMap[childEntry.Key]);
}
}
}
Now I realise this has been a long question, and thanks for reading. But the only question I have is, why do I have to do it this way? Is this something that Breeze doesn't have implemented yet? If so, is the way I've done it ok?
You've uncovered a bug ... or so it seems to me. I have filed it and we'll let you know when it is fixed.
On a different note, your BreezeJS client code is a little more tortured than it needs to be. Why create an uninitialized detached entity ... and then add it?
The line user.Person(user); doesn't seem right at all. That should fail. I think you meant user.Person(person);. But you won't need that either.
Try this:
var manager = new breeze.EntityManager('api/Db');
// other initialization stuff.
// adds new, initialized Person entity
var person = manager.createEntity('Person', {
// perhaps init fields: firstName, lastName
});
// adds new, initialized User entity, associated w/ parent Person
var user = manager.createEntity('User', {
personId: person.Id(), // SETS THE KEY TO PARENT PERSON
// perhaps init fields: emailAddress, password (really!?!)
});
manager.saveChanges().then(function() { ... etc.
Update 8 May 2013
Yes, that commit is the fix on the BreezeJS side. We'll release it soon ... although of course you are free to grab an intermediate commit. I wouldn't ... because intermediate, untagged commits haven't been properly QA'd.
I think you will still have a problem ... this time on the EntityFramework side. 1-1 is pretty trick in Code First; you may want to look at this StackOverflow thread.
To be specific to your case, I think you need to change your definition of User to this:
public class User {
[Key]
[ForeignKey("Person")]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
//[Required]
public virtual Person Person { get; set; }
[Required]
public string EmailAddress { get; set; }
[Required]
public string Password { get; set; }
}
You shouldn't need the "Fluent API" mapping for User that you show above and it might get in the way.
// DELETE THIS !!!
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity().HasRequired(x => x.Person);
}
FWIW, the Order/InternationalOrder relationship in DocCode is virtually the same as your Person/User. The test, "can save a new Northwind Order & InternationalOrder [1..(0,1) relationship]", in the saveNorthwindTests.js confirms the model definition and the Breeze fix.
Hope this helps.
Breeze v 1.3.3 is now available on the Breeze website and we did fix an issue with 1-1 mappings. Could you confirm whether this corrects your issue?

Categories