Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I do not want do bind the Id property on my CustomerViewModel so I added a [BindNever] attribute but it is not working. What could be the solution?

I have the following:

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; }
}

If I input the following json . The id property still gets binded

{
  "id": 100,
  "lastName": "Bruce",
  "firstName": "Wayne",
  "email": "bruce@gothamcity.com"
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
219 views
Welcome To Ask or Share your Answers For Others

1 Answer

This Blog post is an interesting read and concludes that the [FromBody] annotation "overrides" the BindBehaviourAttribute (BindNever is a simple specialization). The model is populated by all data available from the body (your JSON data in this case).

I do not consider this as intuitive, and the issue has a nice statement about this:

[BindRequired] customizes the MVC model binding system . That's its purpose and it's working as designed.

[FromBody] switches the affected property or parameter into the different world of input formatting. Each input formatter (e.g. Json.NET and a small MVC-specific wrapper) can be considered a separate system with its own customization. The model binding system has no knowledge the details of JSON (or any other) deserialization.

Lesson learned: BindNever does not work in this scenario.

What are alternatives ?

Solution 1: Writing some custom model binding code. I have not done it myself, but What is the correct way to create custom model binders in MVC6? may help.

Solution 2: Rather pragmatic one

Perhaps this simple (but not very nice) workaround helps you out:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...