2016-10-07 1 views
2

Je ne veux pas lier la propriété Id sur mon CustomerViewModel alors j'ai ajouté un attribut [BindNever] mais cela ne fonctionne pas. Quelle pourrait être la solution?Pourquoi l'attribut BindNever ne fonctionne pas

Je donne les résultats suivants:

CustomerController.cs

// PUT api/customers/5 
[HttpPut("{id}")] 
public async Task<IActionResult> Put([FromUri] int id, [FromBody]CustomerViewModel customer) 
{ 
    //Implementation 
} 

CustomerViewModel

public class CustomerViewModel 
{ 
    [BindNever] 
    public int Id { get; set; } 
    public string LastName { get; set; } 
    public string FirstName { get; set; } 
    public string Email { get; set; } 
} 

Si je l'entrée JSON suivante. La propriété se id encore binded

{ 
    "id": 100, 
    "lastName": "Bruce", 
    "firstName": "Wayne", 
    "email": "[email protected]" 
} 

Répondre

4

Ce Blog post est une lecture intéressante et conclut que l'annotation [FromBody] « remplace » l'BindBehaviourAttribute (BindNever est une simple spécialisation). Le modèle est rempli par toutes les données disponibles dans le corps (vos données JSON dans ce cas).

Je ne considère pas cela comme intuitive et le issue a une belle déclaration à ce sujet:

[BindRequired] personnalise le système de fixation du modèle MVC. C'est son but et il fonctionne comme prévu.

[FromBody] commute la propriété affectée ou d'un paramètre dans le monde différent de la mise en forme d'entrée. Chaque formateur d'entrée (par exemple Json.NET et un petit wrapper spécifique à MVC) peut être considéré comme un système distinct avec sa propre personnalisation. Le système de liaison de modèle n'a aucune connaissance des détails de la désérialisation JSON (ou de toute autre).

Leçon apprise: BindNever ne fonctionne pas dans ce scénario.

Quelles sont les alternatives?

Solution 1: écriture d'un code de liaison de modèle personnalisé. Je ne l'ai pas fait moi-même, mais What is the correct way to create custom model binders in MVC6? peut aider.

Solution 2: Plutôt pragmatique

Peut-être que ce simple (mais pas très agréable) solution vous aide:

[HttpPut("{id}")] 
public async Task<IActionResult> Put([FromUri] int id, [FromBody]CustomerViewModel customer) 
{ 
    customer.Id = 0; 
    //Implementation 
} 
+0

Avoir un setter privé semble faire l'affaire. Je ne peux pas valider ma solution. J'ai essayé de regarder autour de moi pour trouver quelque chose de similaire mais sans chance. –