You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.0 MVC:调用TryUpdateModelAsync前如何程序化修改字段值

How to Modify Field Values Programmatically Before Calling TryUpdateModelAsync in .NET Core MVC

Great question! I’ve run into this exact scenario building CRUD workflows with EF Core, and there are a couple of clean, straightforward ways to handle modifying fields like DateUpdated or adjusting values based on form input before executing the update with TryUpdateModelAsync. Let’s break it down with practical examples.

Core Workflow: Retrieve the Entity First, Then Modify

First, you need to fetch the existing entity from the database—TryUpdateModelAsync requires a live entity instance to apply form values to. Once you have that entity, you can tweak fields before letting the model binder update the form-specific properties.

Example 1: Setting Static Audit Fields (Like DateUpdated)

This is the most common use case—setting fields that don’t come from the user’s form input:

public async Task<IActionResult> Edit(int id)
{
    // Step 1: Fetch the existing entity from your database
    var yourEntity = await _context.YourEntities.FindAsync(id);
    if (yourEntity == null)
    {
        return NotFound();
    }

    // Step 2: Modify fields BEFORE calling TryUpdateModelAsync
    yourEntity.DateUpdated = DateTime.UtcNow; // Use UtcNow for timezone consistency
    yourEntity.LastUpdatedBy = User.Identity.Name; // Capture the current user

    // Step 3: Apply form values to the entity (use an allow-list to prevent overposting!)
    if (await TryUpdateModelAsync<YourEntity>(
        yourEntity,
        "", // Empty prefix since we're binding directly to the entity
        e => e.Name, e => e.Description, e => e.Price)) // Only allow these fields to be updated
    {
        try
        {
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        catch (DbUpdateException)
        {
            ModelState.AddModelError("", "Failed to save changes. Please try again.");
        }
    }

    // If validation fails, return the view with the existing entity data
    return View(yourEntity);
}

Example 2: Adjusting Fields Based on Form Input

If you need to modify a field based on what the user submitted, you can either read directly from the form or use a view model for cleaner logic:

Option A: Read Directly from Request.Form

public async Task<IActionResult> Edit(int id)
{
    var yourEntity = await _context.YourEntities.FindAsync(id);
    if (yourEntity == null)
    {
        return NotFound();
    }

    // Read a form value to calculate another field's value
    var discountInput = Request.Form["DiscountPercentage"].ToString();
    if (decimal.TryParse(discountInput, out decimal discount))
    {
        // Calculate a discounted price based on the user's input
        yourEntity.DiscountedPrice = yourEntity.OriginalPrice * (1 - discount / 100);
    }

    // Set your audit field
    yourEntity.DateUpdated = DateTime.UtcNow;

    // Apply form updates to allowed fields
    if (await TryUpdateModelAsync<YourEntity>(
        yourEntity,
        "",
        e => e.Name, e => e.OriginalPrice, e => e.DiscountPercentage))
    {
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    return View(yourEntity);
}

Option B: Use a View Model (Cleaner for Complex Logic)

For more involved scenarios, using a view model to capture user input first makes your code more maintainable:

// Define your view model to capture user input
public class YourEntityEditViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal OriginalPrice { get; set; }
    public decimal DiscountPercentage { get; set; }
}

// In your controller action
public async Task<IActionResult> Edit(int id, YourEntityEditViewModel viewModel)
{
    if (id != viewModel.Id)
    {
        return NotFound();
    }

    var yourEntity = await _context.YourEntities.FindAsync(id);
    if (yourEntity == null)
    {
        return NotFound();
    }

    // Adjust entity fields based on view model values
    yourEntity.DiscountedPrice = viewModel.OriginalPrice * (1 - viewModel.DiscountPercentage / 100);
    yourEntity.DateUpdated = DateTime.UtcNow;

    // Map view model values to the entity
    if (await TryUpdateModelAsync<YourEntity>(
        yourEntity,
        "",
        e => e.Name, e => e.OriginalPrice, e => e.DiscountPercentage))
    {
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    // If validation fails, repopulate the view model with entity data
    viewModel.Name = yourEntity.Name;
    viewModel.OriginalPrice = yourEntity.OriginalPrice;
    return View(viewModel);
}

Key Best Practices

  • Always Use an Allow-List: Never skip the field list in TryUpdateModelAsync—this prevents overposting attacks, where malicious users could update fields you didn’t intend (like IsAdmin).
  • Timezone Consistency: Use DateTime.UtcNow instead of DateTime.Now for audit fields to avoid timezone discrepancies across servers.
  • Validation: If modifying fields based on user input, add validation checks (e.g., ensure discount percentage is between 0 and 100) and add model errors if validation fails.

内容的提问来源于stack exchange,提问作者user6383418

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:19:59