ASP.NET MVC 2:带有外键关系和默认 ModelBinder 奇怪的 Linq to SQL 实体

发布于 2024-08-31 01:35:19 字数 1654 浏览 4 评论 0原文

我再次在使用 Linq to Sql 和 MVC Model Binder 时遇到问题。

我有 Linq to Sql 生成的类,为了说明它们,它们看起来类似于:

public class Client
{
    public int ClientID { get; set; }
    public string Name { get; set; }
}

public class Site
{
    public int SiteID { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int UserID { get; set; }
    public string Name { get; set; }
    public int? ClientID { get; set; }
    public EntityRef<Client> Client { get; set; }
    public int? SiteID { get; set; }
    public EntityRef<Site> Site { get; set; }
}

“用户”与“客户端”和“站点”有关系 。 User 类具有可为空的 ClientID 和 SiteID,因为管理员用户未绑定到客户端或站点。

现在我有一个视图,用户可以在其中编辑“用户”对象,该视图具有所有“用户”属性的字段。提交表单后,在我的 UserController 中调用适当的“保存”操作:

public ActionResult Save(User user, FormCollection form)
{
    //form['SiteID'] == 1
    //user.SiteID == 1

    //form['ClientID'] == 1
    //user.ClientID == null
}

这里的问题是 ClientID 从未设置,它始终为 null,即使该值位于 FormCollection 中也是如此。

为了找出问题所在,我在 Linq to Sql 设计器生成的类中为 ClientID 和 SiteID getter 和 setter 设置了断点。我注意到以下几点: 正在设置 SiteID,然后设置 ClientID,但随后将 Client EntityRef 属性设置为 null 值,这反过来又将 ClientID 设置为 null!我不知道为什么以及试图设置 Client 属性的原因是什么,因为站点属性设置器从未被调用,仅调用了 Client 设置器。

从 FormCollection 中手动设置 ClientID,如下所示:

user.ClientID = int.Parse(form["ClientID"].ToString());

抛出“ForeignKeyReferenceAlreadyHasValueException”,因为它之前已设置为 null。我发现的唯一解决方法是使用自定义方法扩展生成的部分 User 类:

Client = default(EntityRef<Client>)

但这不是一个令人满意的解决方案。我不认为它应该这样工作?

请有人赐教。到目前为止,Linq to Sql 让我抓狂!

此致

Once again I'm having trouble with Linq to Sql and the MVC Model Binder.

I have Linq to Sql generated classes, to illustrate them they look similar to this:

public class Client
{
    public int ClientID { get; set; }
    public string Name { get; set; }
}

public class Site
{
    public int SiteID { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int UserID { get; set; }
    public string Name { get; set; }
    public int? ClientID { get; set; }
    public EntityRef<Client> Client { get; set; }
    public int? SiteID { get; set; }
    public EntityRef<Site> Site { get; set; }
}

The 'User' has a relationship with the 'Client' and 'Site
. The User class has nullable ClientIDs and SiteIDs because the admin users are not bound to a Client or Site.

Now I have a view where a user can edit a 'User' object, the view has fields for all the 'User' properties. When the form is submitted, the appropiate 'Save' action is called in my UserController:

public ActionResult Save(User user, FormCollection form)
{
    //form['SiteID'] == 1
    //user.SiteID == 1

    //form['ClientID'] == 1
    //user.ClientID == null
}

The problem here is that the ClientID is never set, it is always null, even though the value is in the FormCollection.

To figure out whats going wrong I set breakpoints for the ClientID and SiteID getters and setters in the Linq to Sql designer generated classes. I noticed the following:
SiteID is being set, then ClientID is being set, but then the Client EntityRef property is being set with a null value which in turn is setting the ClientID to null too! I don't know why and what is trying to set the Client property, because the Site property setter is never beeing called, only the Client setter is being called.

Manually setting the ClientID from the FormCollection like this:

user.ClientID = int.Parse(form["ClientID"].ToString());

throws a 'ForeignKeyReferenceAlreadyHasValueException', because it was already set to null before. The only workaround I have found is to extend the generated partial User class with a custom method:

Client = default(EntityRef<Client>)

but this is not a satisfying solution. I don't think it should work like this?

Please enlighten me someone. So far Linq to Sql is driving me crazy!

Best regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

滥情稳全场 2024-09-07 01:35:19

我刚刚在 MVC 3 中遇到了同样的问题。我认为发生这种情况是因为模型绑定器在创建模型类时设置了模型类的所有公共属性。因此它将 user.ClientID 设置为 1,然后将 user.Client 设置为 null (因为它不存在在表单集合中)。之后 user.ClientID 的值也变为 null
因此,您只需从绑定中排除 User 类的 Client 属性,如下所示:

public ActionResult Save([Bind(Exclude="Client")]User user, FormCollection form)

这对我有用。

I've just run in the same issue with MVC 3. I think this happens because model binder sets all public properties of the model class while creating it. So it sets user.ClientID to 1 and then user.Client to null (because it doesn't exist in form collection). And after that the value of user.ClientID becomes null too.
So you just need to exclude the Client property of the User class from binding like this:

public ActionResult Save([Bind(Exclude="Client")]User user, FormCollection form)

This worked for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文