如何在ASP.NET MVC中保留/保护Edit中的某些字段

时间:2022-07-14 03:34:23

In an Edit action in ASP.NET MVC, certain fields can be hidden from user with HiddenFieldFor. However this doesn't protect the fields (such as ID, data creation date) from being edited.

在ASP.NET MVC的“编辑”操作中,可以使用HiddenFieldFor向用户隐藏某些字段。但是,这不会保护字段(例如ID,数据创建日期)不被编辑。

For example, a model Student has fields Id, Name and Birthday. I like to allow users to update the Name, but not Id nor Birthday.

例如,模型学生具有字段ID,名称和生日。我想允许用户更新名称,但不是ID或生日。

For an Edit action like this

对于像这样的编辑动作

public ActionResult Edit(Student student)
{
    if (ModelState.IsValid)
    {
        db.Entry(student).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(student);
}

How can I prevent Id and Birthday from being edited? Thanks!

如何防止编辑Id和Birthday?谢谢!

2 个解决方案

#1


11  

You should use a view model which contains only the properties that you want to be edited:

您应该使用仅包含要编辑的属性的视图模型:

public class EditStudentViewModel
{
    public string Name { get; set; }
}

and then:

public ActionResult Edit(StudentViewModel student)
{
    ...
}

Another technique which I don't recommend is to exclude certain properties from binding:

我不建议的另一种技术是从绑定中排除某些属性:

public ActionResult Edit([Bind(Exclude = "Id,Birthday")]Student student)
{
    ...
}

or include:

public ActionResult Edit([Bind(Include = "Name")]Student student)
{
    ...
}

#2


1  

I assume you have to have the properties in your Model so that in View you can use them to render useful information e.g. an ActionLink with ID or some readonly Text.

我假设您必须拥有模型中的属性,以便在View中可以使用它们来呈现有用的信息,例如带有ID或一些只读文本的ActionLink。

In this case you can define your model with an explicit binding:

在这种情况下,您可以使用显式绑定定义模型:

[Bind(Include = "Name")]
public class Student
{
    int Id { get; set; }
    int Name { get; set; }
    DateTime Birthday { get; set; }
}

This way when updating your model, if the user submits an extra Id it will not be bound.

这样,在更新模型时,如果用户提交额外的ID,则不会绑定。

Another idea I like is having your model know its bindings per scenario and have them compiler validated:

我喜欢的另一个想法是让你的模型知道每个场景的绑定并让它们经过编译验证:

public class ModelExpression<T>
{
    public string GetExpressionText<TResult>(Expression<Func<T, TResult>> expression)
    {
        return ExpressionHelper.GetExpressionText(expression);
    }
}

public class Student
{
    public static string[] EditBinding = GetEditBinding().ToArray();

    int Id { get; set; }
    int Name { get; set; }
    DateTime Birthday { get; set; }

    static IEnumerable<string> GetEditBinding()
    {
        ModelExpression<Student> modelExpression = new ModelExpression<Student>();
        yield return modelExpression.GetExpressionText(s => s.Name);
    }
}

This way in your Action when calling TryUpdateModel you can pass this information.

这种方式在您调用TryUpdateModel时的Action中可以传递此信息。

#1


11  

You should use a view model which contains only the properties that you want to be edited:

您应该使用仅包含要编辑的属性的视图模型:

public class EditStudentViewModel
{
    public string Name { get; set; }
}

and then:

public ActionResult Edit(StudentViewModel student)
{
    ...
}

Another technique which I don't recommend is to exclude certain properties from binding:

我不建议的另一种技术是从绑定中排除某些属性:

public ActionResult Edit([Bind(Exclude = "Id,Birthday")]Student student)
{
    ...
}

or include:

public ActionResult Edit([Bind(Include = "Name")]Student student)
{
    ...
}

#2


1  

I assume you have to have the properties in your Model so that in View you can use them to render useful information e.g. an ActionLink with ID or some readonly Text.

我假设您必须拥有模型中的属性,以便在View中可以使用它们来呈现有用的信息,例如带有ID或一些只读文本的ActionLink。

In this case you can define your model with an explicit binding:

在这种情况下,您可以使用显式绑定定义模型:

[Bind(Include = "Name")]
public class Student
{
    int Id { get; set; }
    int Name { get; set; }
    DateTime Birthday { get; set; }
}

This way when updating your model, if the user submits an extra Id it will not be bound.

这样,在更新模型时,如果用户提交额外的ID,则不会绑定。

Another idea I like is having your model know its bindings per scenario and have them compiler validated:

我喜欢的另一个想法是让你的模型知道每个场景的绑定并让它们经过编译验证:

public class ModelExpression<T>
{
    public string GetExpressionText<TResult>(Expression<Func<T, TResult>> expression)
    {
        return ExpressionHelper.GetExpressionText(expression);
    }
}

public class Student
{
    public static string[] EditBinding = GetEditBinding().ToArray();

    int Id { get; set; }
    int Name { get; set; }
    DateTime Birthday { get; set; }

    static IEnumerable<string> GetEditBinding()
    {
        ModelExpression<Student> modelExpression = new ModelExpression<Student>();
        yield return modelExpression.GetExpressionText(s => s.Name);
    }
}

This way in your Action when calling TryUpdateModel you can pass this information.

这种方式在您调用TryUpdateModel时的Action中可以传递此信息。