1
I have the following situation, a Person class, with properties Id, Name, Birth, I want to implement a page that can update only the Person Name. My implementation should take a person by their id, and change only the Name field.
I made the implementation below in MVC, but how could I do the same with Webapi, since I don’t have Tryupdatemodel or Updatemodel. I implement functionality with this routine to facilitate generalization in the future.
Controller Code in MVC:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult SetNome()
{
var sample = Pessoa.FindById(12);
TryUpdateModel<Pessoa>(sample);
return Json("sucesso");
}
}
public class Pessoa
{
[Required]
public int Id { get; set; }
[Required]
public string Nome { get; set; }
[Required]
public DateTime? Nascimento { get; set; }
public static Pessoa FindById(int id)
{
return new Pessoa() { Id = 12, Nome = "Meu Nome", Nascimento = Convert.ToDateTime("1989-01-31") };
}
}
View code:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script>
var app = angular.module("MainModule", []);
var MainController = function ($scope, $http) {
var url = 'http://localhost:47107/home/setnome';
//var url = 'http://localhost:47107/api/values';
$scope.pessoa = {};
$scope.pessoa.nome = "xpto";
$scope.enviar = function () {
$http({
url: url,
method: "POST",
data: $scope.pessoa
})
.then(function (response) {
// success
console.log(JSON.stringify(response));
},
function (response) {
// failed
console.log(JSON.stringify(response));
});
}
};
app.controller("MainController", MainController);
</script>
</head>
<body ng-app="MainModule">
<div ng-controller="MainController">
<input id="pessoa.nome" ng-model="pessoa.nome" />
{{pessoa.nome}}
<button ng-click="enviar()">Enviar</button>
</div>
</body>
</html>
Current code in Webapi:
public class ValuesController : ApiController
{
public void Post([FromBody]Pessoa pessoa)
{
var sample = Pessoa.FindById(12);
sample.Nome = pessoa.Nome;
}
}
I wanted to have to abstract the Name field, as it was done in MVC, with Updatemodel, it identifies which fields were sent by View and fills only them, the others it keeps original. With Webapi I have to do this manually.
Here:
if (isEnumerable && property.PropertyType != typeof(string))
also compare withDecimal
andDateTime
. These classes are also considered non-priminal.– Leonel Sanches da Silva
Another thing: this one:
property.SetValue(original, null);
has a poor performance. About 200ms per property set. If you use extensively, I recommend using the Fastmember, which lowers the time between 40 and 50ms per property.– Leonel Sanches da Silva
Hi Gypsy, the "if" I want to check if the property is a Ienumerable<>, as string is a Ienumarable and I do not want her in my routine, I put her in condition. I’m not putting you on the spot because you’re a primitive guy.
– Ricardo Carvalho
When to the Setvalue of the Property, really it is slow, as well as the routine by complete, because it uses Reflection, but only the first execution, the second execution was instantaneous. I measured the time and the complete routine runs at 129ms on the first call, the following calls are 0ms. I do not know this library Fastmember, I will take a look. Thanks for the tips.
– Ricardo Carvalho
Last thing:
var newValues = JsonConvert.DeserializeObject<Pessoa>(json);
. Would not beT
instead ofPessoa
?– Leonel Sanches da Silva
That’s right, I made a mistake there. Thank you Gypsy!
– Ricardo Carvalho