将模型属性发布到控制器而不使用隐藏输入?
我试图让用户评论啤酒。给定基本模型:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Beer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class BeerReview
{
public int Id { get; set; }
public virtual Beer { get; set; }
public virtual User { get; set; }
public string Review { get; set; }
}
我也有一个正在使用的视图模型:
public class BeerReviewViewModel
{
public BeerReview Review { get; set; }
...
}
我有以下控制器操作:
public ActionResult Review(int id)
{
var beer = // get beer by Id
BeerReviewViewModel model = new BeerReviewViewModel
{
BeerReview = new BeerReview
{
Beer = beer.First()
}
};
return View("Review", model);
}
[HttpPost]
public ActionResult Review(BeerReviewViewModel submission)
{
if(ModelState.IsValid)
{
// here is the problem
int id = submission.Review.Beer.Id;
}
}
在我看来,我为用户提供了一个简单的表单来评论啤酒。视图看起来像:
@model MyNamespace.BeerReviewViewModel
<h2>Review Beer: @Model.Review.Beer.Name</h2>
@{
using(Html.BeginForm()){
<div>
@Html.TextAreaFor(b => b.Model.Review.Review)
</div>
<div>
<input type="submit" value="Post Review" />
</div>
}
}
显然,我没有将有关啤酒本身的任何内容发布到控制器,因此 BeerReviewViewModel 中的 Beer 对象始终为 null。我想知道,既然我在表单提交之前已经在视图上有了 Beer 对象,是否有办法告诉表单在 POST 上发送此数据。我尝试在控制器上使用 Bind[Prefix="b"] 但没有成功。我想我总是可以向 BeerReviewViewModel 添加一个 int 并将啤酒 Id 的隐藏值从视图发送到控制器(或为每个啤酒属性发送一个隐藏值)。但同样,这对我来说仍然显得很黑客。任何建议将不胜感激。
I'm trying to allow a user to review a beer. Given the basic models:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Beer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class BeerReview
{
public int Id { get; set; }
public virtual Beer { get; set; }
public virtual User { get; set; }
public string Review { get; set; }
}
I have a view model that I'm using as well:
public class BeerReviewViewModel
{
public BeerReview Review { get; set; }
...
}
I have the following controller actions:
public ActionResult Review(int id)
{
var beer = // get beer by Id
BeerReviewViewModel model = new BeerReviewViewModel
{
BeerReview = new BeerReview
{
Beer = beer.First()
}
};
return View("Review", model);
}
[HttpPost]
public ActionResult Review(BeerReviewViewModel submission)
{
if(ModelState.IsValid)
{
// here is the problem
int id = submission.Review.Beer.Id;
}
}
In my view, I provide a simple form for a user to review a beer. The view looks like:
@model MyNamespace.BeerReviewViewModel
<h2>Review Beer: @Model.Review.Beer.Name</h2>
@{
using(Html.BeginForm()){
<div>
@Html.TextAreaFor(b => b.Model.Review.Review)
</div>
<div>
<input type="submit" value="Post Review" />
</div>
}
}
Obviously I'm not posting anything about the beer itself to the controller, so the Beer object in BeerReviewViewModel is always null. I'm wondering if since I already have my Beer object on the view prior to form submit, if there's a way to tell the form to send along this data on the POST. I've tried using Bind[Prefix="b"] on the controller with no luck. I suppose I could always just add an int to the BeerReviewViewModel and send a hidden value of the beer Id from the view to the controller (or send a hidden value for every beer property). But again, this still seems hack-ish to me. Any advice would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的视图模型需要展平。如果您考虑帖子数据包含的内容,您会看到一系列封装到查询字符串中的键值对。您将无法拥有嵌套对象(除非您的默认构造函数能够构建这些嵌套对象)。
或者您可以编写自己的模型绑定程序,但我发现这解决了错误的问题。
Your view model needs to be flattened. If you think about what that post data contains, you're looking at a series of key-value pairs that get encapsulated into a query string. You won't be able to have nested objects (unless your default ctor has the ability to build those nested objects).
Or you could write your own model binder, but I find that's solving the wrong problem.