使用Web API时的TryUpdateModel for JSON

时间:2015-07-23 09:07:56

标签: asp.net-mvc asp.net-web-api

我们在System.Web.ModelBinding下有TryUpdateModel,可以根据源中的可用数据部分更新模型。

如何在Web API中使用此模式?假设我的JSON结果只包含10个字段中的9个,我是否必须逐个设置字段值?

1 个答案:

答案 0 :(得分:1)

我假设:键入的模型和实体框架。我自己正在考虑这个问题,但据我所知,如果您将API值发布到API,那么它们将被初始化为默认值(例如,对于字符串为null),或者如果您包含验证属性,那么API可能会使模型失败验证步骤。

我遇到了在new和update命令中覆盖已创建和更新的时间戳的问题。的?运算符帮助创建,但更新已关闭,然后我找到了DatabaseGenerated属性,这是我需要的。

    [Column("db_created")]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime? Created { get; set; }

如果您不想使用默认值覆盖某些字段,那么您需要使用当前实例进行手动映射。因此,获取并更新您已更改的值。注意:您需要更新从数据库中获取的新对象,因为EF在保存更改时正在跟踪该实例。

例如:

    // PUT: api/Customer/5
    [ResponseType(typeof(void))]
    public async Task<IHttpActionResult> PutCustomer(int id, Customer updatedCustomer)
    {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        if (id != updatedCustomer.ID)
            return BadRequest();

        var currentCustomer = await db.Customers.FindAsync(id);
        updatedCustomer.Created = currentCustomer.Created;
        currentCustomer.Name = updatedCustomer.Name;
        currentCustomer.Description = updatedCustomer.Description;
        //This is nullable in the model e.g. public DateTime? Updated;
        currentCustomer.Updated = null;
        db.Entry(currentCustomer).State = EntityState.Modified;

        try
        {
            await db.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!CustomerExists(id))
                return NotFound();
            else
                throw;
        }
        return StatusCode(HttpStatusCode.NoContent);
    }