【问题标题】:Asp.Net MVC - Binding of parameter to model value!Asp.Net MVC - 将参数绑定到模型值!
【发布时间】:2026-02-08 15:45:02
【问题描述】:

这似乎是模型绑定引起了我的问题。

基本上我有一个名为 ProductOption 的模型,就这个问题而言,它有 2 个字段

ID (Int) PK ProductID (Int) FK

我有一个标准路线设置

    context.MapRoute(
        "Product_default",
        "Product/{controller}/{action}/{id}",
        new { controller = "Product", action = "Index", id = UrlParameter.Optional }
    );

如果用户想添加一个选项,则 URL 是,

/产品/选项/添加/1

在上面的 URL 中 1 是 ProductID,我有下面的代码来返回一个空白模型的视图,

[HttpGet]
public ActionResult Add(int id)
{
    return View("Manage", new ProductOptionModel() { ProductID = id });
}

现在在我看来,我保留了一个隐藏字段

<%= Html.HiddenFor(x=>x.ID) %>

这用于确定(提交时)我们是否正在编辑或添加新选项。然而,.net 中的模型绑定器似乎将 .ID(离开上述 get actionresult 时为 0)替换为 1(或 URL 中 id 参数的值)

我怎样才能停止或解决这个问题?

视图模型

public class ProductExtraModel
{
    //Database 
    public int ID { get; set; }
    public string Name { get; set; }
    public int ProductID { get; set; }

    public ProductModel Product { get; set; }
}

【问题讨论】:

  • 您的代码暗示它在模型中称为 ProductID 而不是 .ID?
  • 能贴出视图模型代码吗?
  • 看看 Alex 的帖子这样做是有意义的

标签: c# asp.net asp.net-mvc


【解决方案1】:

我认为id 参数正在设置,因为默认情况下,您的路线会设置它。在控制器内部,您在 ProductID 的 ViewModel 中设置了一个附加参数,这可能始终等于 ID 参数,因为两者基本上都设置为 QueryString / GET 参数。 (在这种情况下为 1)。

当您阻止它分配 ID 参数时,您更改路由的修复工作似乎是一个不错的选择,但可能并不理想 - 取决于您要如何解决问题:

context.MapRoute(
  "Product_addoptionalextra",
  "Product/{controller}/Add/{ProductID}",
  new { controller = "Product",action="Add", ProductID = UrlParameter.Optional }
);

或者,重新排列您的变量,使 ID 实际上是相关的 ProductID,然后您可以使用代表 ID 的 OtherID。

如果您有 MVC 2,我可能会建议解决此问题的方法是使用 EditorTemplates / DisplayTemplates。虽然我不知道你的ProductViewModel,但我认为它里面有 ID。如果您设置了适当的模板,您几乎可以忘记可能重叠的 ID。

public class ProductExtraModel
{
   //Database 
  public int ID { get; set; }
  public string Name { get; set; }

  [UIHint("Product")]
  public ProductModel Product { get; set; }
}

当模型使用productExtraViewModel.Product.ID 传回控制器时,您将能够访问产品 ID,并且您的正常 ID 仍可在 productViewModel.Id 上使用。

【讨论】:

    【解决方案2】:

    我已经通过更新我的路线解决了这个问题(对此并不完全满意 - 但它有效)

     public override void RegisterArea(AreaRegistrationContext context)
            {
                context.MapRoute(
                   "Product_addoptionalextra",
                   "Product/{controller}/Add/{ProductID}",
                   new { controller = "Product",action="Add", ProductID = UrlParameter.Optional }
                );
    
                context.MapRoute(
                    "Product_default",
                    "Product/{controller}/{action}/{id}",
                    new { controller = "Product", action = "Index", id = UrlParameter.Optional }
                );         
            }
    

    【讨论】: