This seems like the model binding is causing me issues.
看起来模型绑定引起了我的问题。
Essentially I have a model called ProductOption and for the purpose of this question it has 2 fields
本质上,我有一个叫做ProductOption的模型,为了这个问题它有两个字段。
ID (Int) PK ProductID (Int) FK
ID (Int) PK ProductID (Int) FK
I have a standard route set-up
我有一个标准的路线设置
context.MapRoute(
"Product_default",
"Product/{controller}/{action}/{id}",
new { controller = "Product", action = "Index", id = UrlParameter.Optional }
);
and if the user wants to add an option the URL is,
如果用户想添加一个选项URL是,
/Product/Options/Add/1
/产品/选项/添加/ 1
in the above URL 1 is the ProductID, I have the following code to return a blank model the the view,
在上面的URL 1是ProductID,我有以下代码返回一个空模型视图,
[HttpGet]
public ActionResult Add(int id)
{
return View("Manage", new ProductOptionModel() { ProductID = id });
}
Now in my view I keep a hidden field
在我看来,我有一个隐藏的领域
<%= Html.HiddenFor(x=>x.ID) %>
This is used to determine (on submit) if we are editing or adding a new option. However the Model binder in .net seems to replace .ID (Which was 0 when leaving the above get actionresult) with 1 (or the value of the id parameter in the URL)
如果我们正在编辑或添加一个新选项,则使用此选项来确定(提交)。然而。net中的模型绑定器似乎将.ID(在保留上面的get actionresult时为0)替换为1(或URL中id参数的值)
How can I stop or work around this?
我怎样才能停止或者解决这个问题呢?
ViewModel
视图模型
public class ProductExtraModel
{
//Database
public int ID { get; set; }
public string Name { get; set; }
public int ProductID { get; set; }
public ProductModel Product { get; set; }
}
2 个解决方案
#1
2
I think the id
parameter is being set because by default, your route sets it. Inside your controller, you're setting an additional parameter in your ViewModel of ProductID, this will probably always equal the ID parameter as both are basically being set to the QueryString / GET parameter. (1 in this case).
我认为id参数正在设置,因为默认情况下,您的路由会设置它。在控制器中,您正在ProductID的ViewModel中设置一个附加参数,这可能总是等于ID参数,因为这两个参数基本上都被设置为QueryString / GET参数。在这种情况下,(1)。
Your fix of changing the route works as you stop it from allocating the ID parameter seems a good choice, but maybe not ideal - depending on how you want to solve the issue:
当您阻止路由分配ID参数时,更改路由的做法似乎是一个不错的选择,但可能并不理想——这取决于您希望如何解决这个问题:
context.MapRoute(
"Product_addoptionalextra",
"Product/{controller}/Add/{ProductID}",
new { controller = "Product",action="Add", ProductID = UrlParameter.Optional }
);
Alternatively, re-arrange your variables so that ID is actually the relevant ProductID, then you could have OtherID which represents ID.
或者,重新排列变量,使ID实际上是相关的ProductID,然后您可以有代表ID的OtherID。
The way I would maybe suggest to fix this problem if you have MVC 2, is to use EditorTemplates / DisplayTemplates. Although I don't know your ProductViewModel
, I assume it has the ID within it. If you set the appropriate template, you can almost forget about the potentially overlapping IDs.
如果您有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; }
}
You'll be able to access the product ID when the model is passed back into the controller using productExtraViewModel.Product.ID
and your normal ID will still be available on productViewModel.Id
.
当使用productextraview . product将模型传回控制器时,您将能够访问产品ID。ID和您的普通ID仍然可以在productViewModel.Id上使用。
#2
0
I've fixed this by updating my routes (Not completley happy with it - but it works)
我通过更新我的路线来解决这个问题(对它并不完全满意——但它确实有效)
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 }
);
}
#1
2
I think the id
parameter is being set because by default, your route sets it. Inside your controller, you're setting an additional parameter in your ViewModel of ProductID, this will probably always equal the ID parameter as both are basically being set to the QueryString / GET parameter. (1 in this case).
我认为id参数正在设置,因为默认情况下,您的路由会设置它。在控制器中,您正在ProductID的ViewModel中设置一个附加参数,这可能总是等于ID参数,因为这两个参数基本上都被设置为QueryString / GET参数。在这种情况下,(1)。
Your fix of changing the route works as you stop it from allocating the ID parameter seems a good choice, but maybe not ideal - depending on how you want to solve the issue:
当您阻止路由分配ID参数时,更改路由的做法似乎是一个不错的选择,但可能并不理想——这取决于您希望如何解决这个问题:
context.MapRoute(
"Product_addoptionalextra",
"Product/{controller}/Add/{ProductID}",
new { controller = "Product",action="Add", ProductID = UrlParameter.Optional }
);
Alternatively, re-arrange your variables so that ID is actually the relevant ProductID, then you could have OtherID which represents ID.
或者,重新排列变量,使ID实际上是相关的ProductID,然后您可以有代表ID的OtherID。
The way I would maybe suggest to fix this problem if you have MVC 2, is to use EditorTemplates / DisplayTemplates. Although I don't know your ProductViewModel
, I assume it has the ID within it. If you set the appropriate template, you can almost forget about the potentially overlapping IDs.
如果您有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; }
}
You'll be able to access the product ID when the model is passed back into the controller using productExtraViewModel.Product.ID
and your normal ID will still be available on productViewModel.Id
.
当使用productextraview . product将模型传回控制器时,您将能够访问产品ID。ID和您的普通ID仍然可以在productViewModel.Id上使用。
#2
0
I've fixed this by updating my routes (Not completley happy with it - but it works)
我通过更新我的路线来解决这个问题(对它并不完全满意——但它确实有效)
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 }
);
}