Webapi. Define default Json value when enum property is missing - asp.net

I have a webapi that accepts Post as followed (example)
public Foo Post(MyInfo info)
{
return new Foo();
}
MyInfo could be something like this
public class MyInfo
{
[JsonProperty(PropertyName = "n")]
public int MyInt1{ get; set; }
[JsonProperty(PropertyName = "v")]
public string MyString1{ get; set; }
}
Everything works fine when my desktop application (version 1) post a request to this webapi. I serialize the object with a JsonConverter.
Now let's say, I want to add a new parameter to MyInfo as followed
public class MyInfo
{
[JsonProperty(PropertyName = "n")]
public int MyInt1{ get; set; }
[JsonProperty(PropertyName = "v")]
public string MyString1{ get; set; }
[JsonProperty(PropertyName = "s")]
public MyEnum EnumValue{ get; set; }
}
I update the website and the webapi and I publish a new version of my desktop application (version 2).
The webapi works fine with the version 2 of my desktop application. However, when I use my version 1, the parameter (MyInfo info) in the webapi ends null.
As a reminder, the version 1 sends the exact same MyInfo object except that one property is missing.
How can I avoid this problem and define a default value if the property is missing.
Thanks

Well in fact the problem was that I had two properties with the same Json property name.
It was completly unrelated to the default value.

Related

Issue while passing null values to nullable properties in web api call in .netcore web api project

I am facing issue while passing null parameter values to properties of my model in HttpGet verb.
I am using .Net Core 2.1 for my web API project. Below is my action method in controller:
[HttpGet("get")]
public ActionResult GetData([FromQuery]MyTestModel model)
{
var result = new MyTestModel();
return new JsonResult(result);
}
And my MyTestModel.cs is like :
[Serializable]
public class MyTestModel
{
public MyTestModel()
{
PageNo = 1;
PageSize = 10;
}
public int ClientId { get; set; }
public int? CandidateId { get; set; }
public DateTime? FromDate { get; set; }
public DateTime? ToDate { get; set; }
public int PageNo { get; set; }
public int PageSize { get; set; }
}
When I call the API like :
api/controller/get?clientId=7583&candidateId=null&fromDate=null&toDate=null
I am getting 400 response. Below is the response message:
{"toDate":["The value 'null' is not valid for ToDate."],
"fromDate":["The value 'null' is not valid for FromDate."],
"candidateId":["The value 'null' is not valid for CandidateId."]
}
When I don't send nullable properties at all(candidateId, fromDate,toDate), this hits my action and uses default values as null.
What's the problem if I am trying to explicitly setting null values?
Do I need to set some configuration in my Startup.cs to handle null values for nullable properties?
Any help will be appreciated .
Thanks in advance.
Everything sent in the query string is just a string. So, when you do something like toDate=null, you're actually saying "set toDate to "null"", i.e. the string "null". The modelbinder attempts to convert all the strings to the actual types you're binding to, but there's no conversion available that can turn "null" into a null DateTime.
To set the value to null, you need to either pass no value toDate= or just omit the key entirely from the query string.

SQLite.net database with Xamarin.Forms App

I have a problem with an SQLite database in my Xamarin.Forms PCL project.
I have followed this example from Microsoft Docs:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/databases
I've been using my own types to store data and it's worked Ok for simple custom types, but I've recently added List<int> and Attendance type to the custom object (Info).
Now when I try and create the object, i get the following errors:
Don't know about System.Collections.Generic.List`1[System.Int32]
Don't know about MyApp.Attendance
Here is the init code:
readonly SQLiteAsyncConnection database;
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<UserPrefrences>().Wait();
database.CreateTableAsync<Attendance>().Wait();
database.CreateTableAsync<Info>().Wait();
I'm using Xamarin.Forms with Xamarin.iOS.
You can not store them by default like that. However there is sqlite-net-extensions which you can use to accomplish that. You can take a look about sqlite-net-extensions here.
Using this extension you will be able to do that with TextBlob property, something like this:
public class Address
{
public string StreetName { get; set; }
public string Number { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
public class Person
{
public string Name { get; set; }
[TextBlob("PhonesBlobbed")]
public List<string> PhoneNumbers { get; set; }
[TextBlob("AddressesBlobbed")]
public List<Address> Addresses { get; set; }
public string PhonesBlobbed { get; set; } // serialized phone numbers
public string AddressesBlobbed { get; set; } // serialized addresses
}
More explanation about TextBlob from url.
Text blobbed properties Text-blobbed properties are serialized into a text property when saved and deserialized when loaded. This allows
storing simple objects in the same table in a single column.
Text-blobbed properties have a small overhead of serializing and
deserializing the objects and some limitations, but are the best way
to store simple objects like List or Dictionary of basic types or
simple relationships.
Text-blobbed properties require a declared string property where the
serialized object is stored.
I just saw that there is also similar/same questions about this topic on StackOverflow already, so you can take a look at them also.
How can you store lists of objects in SQLite.net?
Can I use a List of String in a class intended for SQLite?

ASP.NET Core Entity Framework get related data object

Every time I am trying to get a related object I get error
Object reference not set to an instance of an object
Relevant code:
public class Project
{
public int ProjectId { get; set; }
public string ProjName { get; set; }
public string Description { get; set; }
public virtual List<Developer> MyDevs { get; set; }
}
public class Developer
{
public string Name { get; set; }
public string Skills { get; set; }
public string Email { get; set; }
public virtual Project MyProj { get; set; }
}
//define relationship using fluent api, under AppDbContext
modelBuilder.Entity<Developer>()
.HasOne(d => d.MyProj)
.WithMany(p => p.MyDevs)
.HasForeignKey("ProjectForeignKey");
Add-migration and update-database give no error, but I am not able to find the myDev column in the Project table. I am not able to find the myProj column in the Developer table either, only the foreignkey column.
Running the following seed method adds one project and one developer to the db as expected.
public static void Seed(IApplicationBuilder applicationBuilder)
{
AppDbContext context = applicationBuilder.ApplicationServices.GetRequiredService<AppDbContext>();
Project ProjA = new Project { ProjName = "handyApp", Description = "a dummy Project" };
context.Project.Add(projA);
Developer FirstDev = new Developer { UserName = "John Smith", Skills = "C#", Email = "jsmith#dummymail.com", MyProj = ProjA};
context.Developer.Add(FirstDev);
context.SaveChanges();
}
Then running the following code hits the "Object reference not set to an instance of an object" exception.
Developer Dev = context.Devs.Find(1);
string name = Dev.MyProj.ProjName; //put a break point here, the dubugger tells me Dev.MyProj is null
Please can anyone help to identify what is wrong with my relationship definition.
As # Ivan Stoev pointed out, Lazy loading is not yet supported by EF Core.
https://learn.microsoft.com/en-us/ef/core/querying/related-data

ASP.NET Web API - Entity Framework - 500 Internal Server Error On .Include(param => param.field)

I am currently working on a Web API project with a Database-First method using Entity Framework (which I know is not the most stable of platforms yet), but I am running into something very strange.
When the GET method within my APIController tries to return all records in a DbSet with a LINQ Include() method involved such as this, it will return a 500 error:
// GET api/Casinos
public IEnumerable<casino> Getcasinos()
{
var casinos = db.casinos.Include(c => c.city).Include(c => c.state);
return casinos.AsEnumerable();
}
Yet, this method works fine, and returns my data from within my database:
// GET api/States
public IEnumerable<state> Getstates()
{
return db.states.AsEnumerable();
}
So I have proved in other instances that if it returns the entities without LINQ queries, it works great, yet when there is an Include method used upon the DbContext, it fails.
Of course, trying to find this error is impossible, even with Fiddler, Chrome/Firefox dev tools, and adding in GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
If anyone has resolved this, it would be nice to know a nice resolution so I can start returning my data! Thanks!:)
P.S. I am using SQL Server 2012
This is happening due to error in serialization (Json/XML). The problem is you are directly trying to transmit your Models over the wire. As an example, see this:
public class Casino
{
public int ID { get; set; }
public string Name { get; set; }
public virtual City City { get; set; }
}
public class State
{
public int ID { get; set; }
public string Name { get; set; }
[XmlIgnore]
[IgnoreDataMember]
public virtual ICollection<City> Cities { get; set; }
}
public class City
{
public int ID { get; set; }
public string Name { get; set; }
public virtual State State { get; set; }
[XmlIgnore]
[IgnoreDataMember]
public virtual ICollection<Casino> Casinos { get; set; }
}
public class Context : DbContext
{
public Context()
: base("Casino")
{
}
public DbSet<Casino> Casinos { get; set; }
public DbSet<State> States { get; set; }
public DbSet<City> Cities { get; set; }
}
Pay attention to the XmlIgnore and IgnoreDataMember. You need to restrict avoiding serialization so it doesn't happen in circular manner. Further, the above model will still not work because it has virtual. Remove virtual from everywhere namely City, Cities, Casinos and State and then it would work but that would be inefficient.
To sum up: Use DTOs and only send data that you really want to send instead of directly sending your models.
Hope this helps!
I had same problem in ASP.Net Core Web Api and made it working with this solution:
Add Microsoft.AspNetCore.Mvc.NewtonsoftJson nuget package to web api project.
and in Startup.cs class in ConfigureServices method add this code:
services.AddControllersWithViews().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);

Deserializing a PHP json encoded (json_encode) string with ASP.NET webservices

I am really struggling deserializing a PHP json encoded string in ASP.NET.
I am using nusoap and CakePHP 1.3 on the PHP side and mvc.net 4.0 on the web service side and everything was working well. However, I couldn’t figure out how to pass a complex array as one parameter of the webservice, so I had the idea of serializing it as json and passing a simple string. So far so good...
But I cannot for the life of me de-serialize the json_encoded string in ASP.NET [well, I’ve been trying for the last two hours at least ;)]
Here is what I have so far:
The PHP sends an array of products (product id as a GUID - sent as a string then converted on the web service side) and the number of products:
$args['products'] = json_encode($booking['Booking']['prs_products']);
This is received ok by the webservice as the following json string (products):
[{"BookingProducts":{"id":"2884f556-67ed-4eb8-98ca-a99dc27a2665","quantity":2}},{"BookingProducts":{"id":"f57854ba-0a9b-400b-bea0-bafdcb179b01","quantity":2}},{"BookingProducts":{"id":"7ff81128-c33c-4e6c-a33c-3ca40ccfb5d0","quantity":2}}]
I then try and populate a BookingProducts List<>. The BookingProducts class is as follows:
public class BookingProducts
{
public String id { get; set; }
public int quantity { get; set; }
public BookingProducts()
{
}
public BookingProducts(string id, int quantity)
{
this.id = id;
this.quantity = quantity;
}
}
I have tried both the [System.Web.Script.Serialization][2] and Newtonsoft.Json libraries as follows, but without success:
List<BookingProducts> productsList = new List<BookingProducts>();
try
{
productsList = JsonConvert.DeserializeObject<List<BookingProducts>>((products));
}
catch (Newtonsoft.Json.JsonSerializationException)
{
productsList = new JavaScriptSerializer().Deserialize<List<BookingProducts>>(products);
}
In both cases I get a list of empty products (or a serialization exception).
Hopefully someone has done this before, or can spot an obvious mistake!
What you really have here is a list of objects containing BookingProducts object. In order to deserialize it, you need to have something like this for your entity:
public class BookingProductsWrapper
{
public class BookingProductsInner
{
public string id { get; set; }
public int quantity { get; set; }
}
public BookingProductsInner BookingProducts { get; set; }
}
Now you can deserialize it using JavaScriptSerializer (for example):
System.Web.Script.Serialization.JavaScriptSerializer jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
List<BookingProductsWrapper> productsList = jsSerializer.Deserialize<List<BookingProductsWrapper>>(products);
That will do the trick.

Resources