NiceToMytyuk
NiceToMytyuk

Reputation: 4307

How to ignore object property on .GET but allow it on .POST?

I have the following object in my c# web api project:

public class InfoUtente
{
    public string nome { get; set; }
    public string cognome { get; set; }
    public string cellulare { get; set; }
    public string email { get; set; }
    public bool termini { get; set; }
    public string fidelity { get; set; }

    public InfoUtente() { }
    public InfoUtente(string nome, string cognome, string cellulare, string email, string fidelity)
    {
        this.nome = nome;
        this.cognome = cognome;
        this.cellulare = cellulare;
        this.email = email;
        this.fidelity = fidelity;
    }
}

When a .POST call is made to the server InfoUtente is posted and in this case i should ignore the fidelity property and allow termini

while when the user request the data with a .GET request i should return the whole object with fidelity but without termini.

I'm using the default serializator (JSON.NET), and i've tryed to use JsonIgnore on termini and in a .GET call it returns the right json without termini but if i try to make a .POST of InfoUtente with JsonIgnore on termini property, it will be ignored in .POST too and it's value will be set to false in any case..

So i should be able to .POST a JSON with

nome,cognome,cellulare,email,termini

and be able to .GET it with

nome,cognome,cellulare,email,fidelity

Should i make two different objects one with termini and without fidelity to use in .POST and another without termini and with fidelity to .GET or i could achieve it by using only one object?

Upvotes: 1

Views: 1511

Answers (2)

Roman Ryzhiy
Roman Ryzhiy

Reputation: 1656

One of the possible ways is two interfaces with a custom Contract Resolver class. Assuming in addition to your class we have

public interface InfoUtentePost
{
    public string nome { get; set; }
    public string cognome { get; set; }
    public string cellulare { get; set; }
    public string email { get; set; }
    public bool termini { get; set; }
}

public interface InfoUtentGet
{
    public string nome { get; set; }
    public string cognome { get; set; }
    public string cellulare { get; set; }
    public string email { get; set; }
    public string fidelity { get; set; }
}

Let's create a contract resolver

public class InterfaceContractResolver : DefaultContractResolver
{
    private readonly Type _InterfaceType;
    public InterfaceContractResolver(Type InterfaceType)
    {
        _InterfaceType = InterfaceType;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        //IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
        IList<JsonProperty> properties = base.CreateProperties(_InterfaceType, memberSerialization);
        return properties;
    }
}

This is it, actually. The only thing we have to do now is to use JsonConvert.SerializeObject with some parameters:

InfoUtentePost product = new InfoUtente();

var settings = new JsonSerializerSettings()
{
    ContractResolver = new InterfaceContractResolver(typeof(InfoUtentePost))
};

string output = JsonConvert.SerializeObject(product, typeof(InfoUtentePost), settings);
 // output = "{\"nome\":null,\"cognome\":null,\"cellulare\":null,\"email\":null,\"termini\":false}"

Upvotes: 0

MarleneHE
MarleneHE

Reputation: 374

Creating two different classes is indeed the best solution.

You might want to have a look into Data Transfer Objects since they are also meant to achieve exactly what you want to do.

You would then have two classes, in addition to your InfoUtente entity. One for getting information about the particular instance you're interested in :

public class InfoUtenteDto
{
    public string nome { get; set; }
    public string cognome { get; set; }
    public string cellulare { get; set; }
    public string email { get; set; }
    public string fidelity { get; set; }
}

And another one, for creating a new instance :

public class InfoUtenteForCreationDto
{
    public string nome { get; set; }
    public string cognome { get; set; }
    public string cellulare { get; set; }
    public string email { get; set; }
    public bool termini { get; set; }
}

Upvotes: 2

Related Questions