Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ModelState对于ASP.NET MVC 2中模型的私有属性报告为无效_Asp.net Mvc_Architecture_Modelbinders_Modelstate - Fatal编程技术网

Asp.net mvc ModelState对于ASP.NET MVC 2中模型的私有属性报告为无效

Asp.net mvc ModelState对于ASP.NET MVC 2中模型的私有属性报告为无效,asp.net-mvc,architecture,modelbinders,modelstate,Asp.net Mvc,Architecture,Modelbinders,Modelstate,我正在使用ASP.NET MVC 2.0,我正在尝试利用控制器中的模型绑定和modelstate验证。然而,我遇到了一个问题,我想和大家分享一下,看看你们的想法 好的,我的模型类库中有我的干净用户poco namespace Model { public partial class User { public virtual int Id { get; private set; } public virtual string UserNam

我正在使用ASP.NET MVC 2.0,我正在尝试利用控制器中的模型绑定和modelstate验证。然而,我遇到了一个问题,我想和大家分享一下,看看你们的想法

好的,我的模型类库中有我的干净用户poco

namespace Model
{    
    public partial class User
    {
        public virtual int Id { get; private set; }
        public virtual string UserName { get; private set; }
        public virtual string DisplayName { get; set; }
        public virtual string Email { get; set; }

        public User(string displayName, string userName)
            : this()
        {
            DisplayName = displayName;
            UserName = userName;
        }
    }
}
我选择的设计只允许在构建对象后编辑某些属性。例如,用户名只能在构建对象时设置,对我来说这是OO意义上的,但却是我问题的关键,所以我想在这里强调一下

然后我有一个“buddy类”,它为我的用户类定义验证元数据

namespace Model
{
[MetadataType(typeof(UserMetadata))]
public partial class User
{
    class UserMetadata
    {
        [Required]
        public virtual int Id { get; set; }

        [Required]
        public virtual string UserName { get; set; }

        [Required]
        public virtual string DisplayName { get; set; }

        [RegularExpression(@"^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", ErrorMessage = "Invalid address")]
        public virtual string Email { get; set; }
    }
}
}

然后在我的web层中,我希望允许我的用户能够编辑此对象。因此,在我的profile controller中有以下两种操作方法

namespace Web.Controllers
{
    public class ProfileController : Controller
    {
        [Authorize]
        public ActionResult Edit()
        {
            var user = _session.Single<User>(x => x.UserName == HttpContext.User.Identity.Name );
            return View(user);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
        [TransactionFilter]
        public ActionResult Edit(User updatedUser)
        {
            // Get the current user to update.
            var user = _session.Single<User>(x => x.UserName == HttpContext.User.Identity.Name);

            if (ModelState.IsValid)
            {
                TryUpdateModel(user);
                // Update store...                
            }
            return View(updatedUser);
        }
    }
}
名称空间Web.Controllers
{
公共类ProfileController:控制器
{
[授权]
公共行动结果编辑()
{
var user=\u session.Single(x=>x.UserName==HttpContext.user.Identity.Name);
返回视图(用户);
}
[HttpPost]
[ValidateAntiForgeryToken]
[授权]
[交易过滤器]
公共操作结果编辑(用户更新用户)
{
//获取要更新的当前用户。
var user=\u session.Single(x=>x.UserName==HttpContext.user.Identity.Name);
if(ModelState.IsValid)
{
TryUpdateModel(用户);
//更新存储。。。
}
返回视图(updateUser);
}
}
}
这有一个强类型的视图来配合它

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Model.User>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Edit
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <%=Html.Script("jquery.validate.js")%>
    <%=Html.Script("MicrosoftMvcJQueryValidation.js")%>
    <%=Html.Script("MvcFoolproofJQueryValidation.js")%>
    <div class="container">
        <div class="column span-14">
        <% using (Html.BeginForm()) {%>
            <%= Html.AntiForgeryToken() %>
            <fieldset>
                <%: Html.DisplayFor(model => model.UserName) %>
                <%= Html.Label("Display Name") %>
                <%= Html.HiddenFor(model => model.DisplayName)%>
                <%= Html.ValidationMessageFor(model => model.DisplayName)%>
                <%= Html.Label("Email address") %>
                <%= Html.EditorFor(model => model.Email)%>
                <%= Html.ValidationMessageFor(model => model.Email)%>
                <%= Html.HiddenFor(model => model.UserName)%>
                <p>
                    <input type="submit" value="Save" />
                </p>
            </fieldset>
        </div>
        <div class="clear"></div>
        <% } %>
    </div>
</asp:Content>

使用模型视图

这对我来说就是不干?!如果没有合适的现有模型对象(例如,我使用注册模型视图),我很乐意使用这些

CustomModelBinder

我的首选,但我不确定我知道我在做什么!!如果我能让活页夹只绑定到它可以设置的属性,那么我会笑

人们怎么想?对以上选项的评论,任何其他解决方案,我的架构是否偏离了标准

谢谢:)

“我设计为不设置它,因此,通过设计,我不希望模型绑定器设置它,但我不希望出现验证错误。我认为它只会对可以设置的属性产生验证错误。”

请在此处阅读有关此设计决策的更多信息:

有趣的是,大多数人的抱怨与你的抱怨完全相反

你基本上是告诉系统,不能设置的东西应该总是设置好。所以我不会说MVC工作不正常或诸如此类。你只是在编写一个不可能的场景


总的来说,您刚刚达到metadatabuddy技术的痛点。主要是需要对新场景和编辑场景进行不同的验证

“如果我这样做,我会允许自己更改现有用户的用户名。我必须在某个地方添加额外的逻辑来捕捉这一点,这不是很好。我还必须在操作方法上添加一个绑定排除,以阻止任何淘气的人试图通过帖子设置它。”

我不知道你对这些代码更改吃得多饱。您将向单个方法调用添加一个简单字符串。有什么大不了的?我在这里采用务实的方法。

“我设计为不设置它,因此,通过设计,我不希望模型绑定器设置它,但我不希望出现验证错误。我认为它只会对可以设置的属性产生验证错误。”

请在此处阅读有关此设计决策的更多信息:

有趣的是,大多数人的抱怨与你的抱怨完全相反

你基本上是告诉系统,不能设置的东西应该总是设置好。所以我不会说MVC工作不正常或诸如此类。你只是在编写一个不可能的场景


总的来说,您刚刚达到metadatabuddy技术的痛点。主要是需要对新场景和编辑场景进行不同的验证

“如果我这样做,我会允许自己更改现有用户的用户名。我必须在某个地方添加额外的逻辑来捕捉这一点,这不是很好。我还必须在操作方法上添加一个绑定排除,以阻止任何淘气的人试图通过帖子设置它。”


我不知道你对这些代码更改吃得多饱。您将向单个方法调用添加一个简单字符串。有什么大不了的?我会采取务实的方法。我会使用视图模型,因为它最适合这份工作。不要认为DRY意味着不能在两个对象上重复属性,可以认为它是“不要在两个地方重复逻辑或保存相同的数据”。在这种情况下,处理模型绑定的语义与您的域模型不匹配,因此您需要一种方法来转换它。

我会使用视图模型,因为它最适合此工作。不要认为DRY意味着不能在两个对象上重复属性,可以认为它是“不要在两个地方重复逻辑或保存相同的数据”。在这种情况下,处理模型绑定的语义与您的域模型不匹配,因此您需要一种方法来翻译它。

jfar发布了一个不错的链接,指向Brad Wilson的一篇文章,其中Brad评论

您仍然可以进行部分编辑,但是 您不能进行任何部分验证 更多所以如果你排除绑定 带有[必需]的东西 属性,则验证将失败。 你有几个选择要解决 这:

  • 使用准确镜像表单数据的视图模型

  • 调用前,用数据预先填写[必填]但未绑定的字段 (尝试)更新模型,以便 瓦利达