How to make a POST request with postman? - json

I have two models, Sever and Update. The ralationship between these two classes is 1...*N, meaning that each Server has multiple updates.
Here is my Server model:
public class Server
{
public Server()
{
UpdateList = new HashSet<Update>();
}
[Key]
[Required]
public int ID { get; set; }
[Required]
public string ComputerName { get; set; }
[Required]
public string Type { get; set; }
[Required]
public string Estado { get; set; }
[Required]
public string Phase { get; set; }
public virtual ICollection<Update> UpdateList { get; set; }
}
Here is my Update model:
public class Update
{
[Required]
public int ID { get; set; }
public string updateId { get; set; }
public string updateTitle { get; set; }
public string updateDescription { get; set; }
[System.ComponentModel.DataAnnotations.Schema.ForeignKey("Server")]
[Display(Name = "Server")]
public int? ServerFK { get; set; }
public virtual Server Server { get; set; }
}
Here is the POST request that I'm using in postman:
{
"computerName":"ServerTestUpdate",
"type":"ServidorAplicacional",
"estado":"Reboot Pending",
"phase":"0",
"updateList":
[{
"updateId":"idTest",
"updateTitle":"Update1",
"updateDescription":"TestDescription"
}]
}
However, when I do this, I get the following error:
System.Text.Json.JsonException: A possible object cycle was detected.
This can either be due to a cycle or if the object depth is larger
than the maximum allowed depth of 32. Consider using
ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.
Is there something wrong with the syntax or maybe is something in the controller?
Thank you in advance

Most likely this is a problem in serializing the object, since deserialization wouldn’t care about cycles. It’s probably the fact that your Server object has a collection of Updates, all of which have a Server property pointing back and this causes a cycle.
If you add JsonIgnore attribute to the property this should go away (from System.Text.Json.Serialization namespace)
[JsonIgnore]
public virtual Server Server { get; set; }

Related

Parsing JSON in C# 4.0

Can anyone help me to parse this JSON into an object IN C# 4.0. I have spent the last two days trying.
I have JSON.NET and several other peoples suggestions to no avail.
I thought it would be best just to give the JSON sample and to ask for your suggestions.
{
"message-count":"1",
"messages":[
{"to":"441234567890",
"messageprice":"0.02900000",
"status":"0",
"messageid":"030000001DFE2CB1",
"remainingbalance":"1.56500000",
"network":"23433"}
]
}
Many thanks,
Adrian
p.s Their is some nice code here, if you want to use github. https://github.com/lukesampson/HastyAPI.Nexmo
I will cheat and create C# classes quickly using this tool: http://json2csharp.com/ (or just discovered http://jsonclassgenerator.codeplex.com/)
Then I change C# classes to my liking
public class MessagesJSON
{
public int MessageCount { get; set; }
public List<Message> Messages { get; set; }
}
public class Message
{
public string To { get; set; }
public double MessagePrice { get; set; }
public int Status { get; set; }
public string MessageId { get; set; }
public double RemainingBalance { get; set; }
public string Network { get; set; }
}
MessagesJSON is just a name I made that represents the JSON object that you are passing to C#.
I pass the JSON string from the client, e.g.
{\"MessageCount\":1,\"Messages\":[{\"To\":\"441234567890\",\"MessagePrice\":0.029,\"Status\":0,\"MessageId\":\"030000001DFE2CB1\",\"RemainingBalance\":1.565,\"Network\":\"23433\"}]
Then I can use JSON.NET to convert JSON to C# objects:
public void YourMethod(MessagesJSON json) {
var result = JsonConvert.DeserializeObject<MessagesJSON>(json);
}
Here's the result:
Watch out for capitalisation.
If you want to use lower-case JSON keys only, change the C# classes to lower-case, e.g. public double messageprice { get; set; }
C# classes:
public class MessagesJSON
{
public int message_count { get; set; }
public List<Message> messages { get; set; }
}
public class Message
{
public string to { get; set; }
public string messageprice { get; set; }
public string status { get; set; }
public string messageid { get; set; }
public string remainingbalance { get; set; }
public string network { get; set; }
}
This is as close to your JSON as you want:
{\"message_count\":1,\"messages\":[{\"to\":\"441234567890\",\"messageprice\":\"0.02900000\",\"status\":\"0\",\"messageid\":\"030000001DFE2CB1\",\"remainingbalance\":\"1.56500000\",\"network\":\"23433\"}]}
or use one of these solutions if you really like CamelCasing:
CamelCase only if PropertyName not explicitly set in Json.Net?
JObject & CamelCase conversion with JSON.Net
I myself prefer attributes
public class Message
{
[JsonProperty("to")]
public string To { get; set; }
[JsonProperty("messageprice")]
public string MessagePrice { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("messageid")]
public string MessageId { get; set; }
[JsonProperty("remainingbalance")]
public string RemainingBalance { get; set; }
[JsonProperty("network")]
public string Network { get; set; }
}
Pass your string:
"{\"message_count\":1,\"messages\":[{\"to\":\"441234567890\",\"messageprice\":\"0.02900000\",\"status\":\"0\",\"messageid\":\"030000001DFE2CB1\",\"remainingbalance\":\"1.56500000\",\"network\":\"23433\"}]}"
but get the pretty C# property names:
Create objects with the same structure as the json and call.
JsonConvert.DeserializeObject<Entity>(json);
Edit. You have to use JSON.NET if u wanna do it this way.

Self referencing loop detected serialization exception

This is my class:
public partial class Event
{
public Event()
{
this.Comments = new HashSet<Comment>();
this.Rates = new HashSet<Rate>();
this.RawDates = new HashSet<RawDate>();
}
public int ID { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string SiteURL { get; set; }
public string ContactEmail { get; set; }
public string LogoURL { get; set; }
public int EventType_ID { get; set; }
public Nullable<int> Location_ID { get; set; }
public Nullable<System.DateTime> BegginingDate { get; set; }
public string nTrain { get; set; }
public string Content { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual Conference Conference { get; set; }
public virtual ICollection<Rate> Rates { get; set; }
public virtual ICollection<RawDate> RawDates { get; set; }
public virtual EventType EventType { get; set; }
public virtual Location Location { get; set; }
}
When I call web api post method, exception mentioned in the title is thrown in this line:
var response = await client.PostAsJsonAsync("api/event", event);
I added [JsonIgnore] above every virtual field in Event class. This time serialization worked, but ignored fields were not serialized, their value is null. I really need all information contained in Event object. How can I solve this problem?
Adding below configuration in WebAPIConfig.cs resolves the bug.
var json = config.Formatters.JsonFormatter;
//Below configuration to mandatory to resolve the Self referencing loop detected with
"Newtonsoft.Json.JsonSerializationException" ,
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
Circular referencing objects cannot be JSON serialized. I would recommend you using a view model in which you will include the properties you need and then have your action return this view model instead of the actual domain model.

Best approach for my EF 'DataBase'

I've been a few weeks working on a web project, amd mostly thinking how would I implement data layer. I chosed Entity Framework 4.1, code first model.
So, among lot of other entities , think of PLAYER who has N CHARACTER, that can be in 0..1 GUILD
public class Player
{
public int Id { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public bool IsLogged { get; set; }
public DateTime LastActivity { get; set; }
public DateTime LastLogin { get; set; }
public DateTime LastLogout { get; set; }
public string DisplayName { get; set; }
public string DefaultImage { get; set; }
public virtual Board Board { get; set; }
public virtual PlayerData PlayerData { get; set; }
public virtual ICollection<Character> Characters { get; set; }
}
public class Guild
{
public int Id { get; set; }
public string Name { get; set; }
public string DefaultImage { get; set; }
public virtual ICollection<Character> Characters { get; set; }
}
public class Character
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Player Player { get; set; }
public virtual Guild Guild { get; set; }
public virtual GuildRank GuildRank { get; set; }
public virtual Game Game { get; set; }
}
As you can see, there a lot more entities and relationships, but this will work.
Well it does not, this code:
Character character = mod.Characters.Where(c => c.Player == player).FirstOrDefault();
Throws an exception:
Unable to create a constant value of type 'DataObjects.Player'. Only
primitive types ('such as Int32, String, and Guid') are supported in
this context.
I don't understand why.
I also tried with using [Key] and [ForeingKey] attributes, but I can't find them! :S (though the where in System.Data.Entity.dll, but the don't).
So after so many errors, I started to think maybe I got the whole thing wrong...
Any ideas on how to fix the error, or to go in other direction?
Thanks in advance.
This is stupidity in EF. You cannot compare Player directly. You must compare Ids so your query can be rewritten to:
int playerId = player.Id;
Character character = mod.Characters.FirstOrDefault(c => c.Player.Id == playerId);

Code First Object not properly instantiating

I have a class department inheriting from activeentity
public class ActiveEntity : Entity, IActive
{
public ActiveEntity()
{
IsActive = true;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public bool IsActive { get; set; }
[Timestamp, ScaffoldColumn(false), DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Computed)]
public Byte[] Timestamp { get; set; }
[ScaffoldColumn(false)]
public string CreationUserId { get; set; }
[ScaffoldColumn(false)]
public string LastModifiedUserId { get; set; }
}
public class Department:ActiveEntity
{
public Department()
{
this.Address = new DepartmentAddress();
}
[StringLength(9),MinLength(9),MaxLength(9)]
public string Name { get; set; }
public Guid ManagerId { get; set; }
[UIHint("AjaxDropdown")]
public User Manager { get; set; }
public Guid? AddressId { get; set; }
public DepartmentAddress Address { get; set; }
public ICollection<OverheadRate> OverheadRates { get; set; }
}
I am just using annotations no Fluent API. The data saves to the data Sql Server 2008 just fine however the address object never gets instantiated, even though I have the context use the include
return c.Set<Department>().Include(d => d.Address).Include(d => d.Manager).Where(predicate);
The data is returned I run sql profiler and then run the query it returns the correct data.
Any thoughts or suggestions?
Remove instantiating the address (this.Address = new DepartmentAddress();) in the Department constructor. Instantiating navigation references in the default constructor is evil and has nasty side effects like these:
What would cause the Entity Framework to save an unloaded (but lazy loadable) reference over existing data?
EF 4.1 Code First: Why is EF not setting this navigation property?

OpenRasta Json returning nested classes

Is it possible to return nested classes in json with OpenRasta?
I'm using EF4.1 with code first (which in theory shouldn't make a difference, as they are just POCO classes).
Here is an example:
public class AppUser
{
[Key]
public int AppUserId { get; set; }
public string WinLogin { get; set; }
public string ScreenName { get; set; }
public string AgencyId { get; set; }
public virtual ICollection<UserAppVersion> UserAppVersion { get; set; }
}
public class UserAppVersion
{
[Key]
public int UaVersionId { get; set; }
public int AppUserId { get; set; }
public int AppVersionId { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUpdated { get; set; }
public virtual AppUser User { get; set; }
public virtual AppVersion Version { get; set; }
}
I try and return an AppUser record in json using this:
ResourceSpace.Has.ResourcesOfType<AppUser>()
.AtUri("/user").HandledBy<UserHandler>().AsJsonDataContract();
But I get an error:
System.Runtime.Serialization.SerializationException: Type 'System.Data.Entity.DynamicProxies.UserAppVersion_FD8D86F0A3AE39A0C370918637C1A90AD8D3ACA3E149677EA82C0A8D10ED0F8D' with data contract name 'UserAppVersion_FD8D86F0A3AE39A0C370918637C1A90AD8D3ACA3E149677EA82C0A8D10ED0F8D:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Unfortunately I don't know how to resolve this. Any suggestions?
That's a data contract issue, not an openrast one.
The DataContract serialzier is seeing a dynamic proxy probably generated by EF code first, and when seeing that cannot render the object.
I'd recommend either swapping for another serialziation codec, or disabling transparent lazy loading, or alternatively marking your property as an ignore for serialziation and have another property typed to a List so the serializer can function.
See DataContractSerializer Error using Entity Framework 4.0 with WCF 4.0