ASP.NET MVC:阻止用户编辑模型上的某些字段

时间:2012-01-06 03:09:02

标签: asp.net-mvc entity-framework

我有一个模型,它有几个字段,我从来不想被用户编辑。如何创建一个不仅隐藏这些字段的编辑页面,还可以防止用户自己注入输入元素?

由于

4 个答案:

答案 0 :(得分:3)

查看TryUpdateModel()MSDN article found here。)。您可以指定实际更新方法的黑名单和白名单:

public ActionResult MyUpdateMethod (MyModel myModel)
{
    if (ModelState.IsValid)
    {
        var myDomainModel = new DomainModel ();
        if (TryUpdateModel (myDomainModel,
                            new string[] { /* WhiteList Properties here */ },
                            new string[] { /* BlackList Properties here */ })

        {
            // Save it or do whatever
            return RedirectToActionV (/* Yada */);
        }
    }

    return View (myModel);
    }
}

除此之外,我还要确保您发布的模型不包含您希望用户更新的字段,但可以使用手工制作的表单帖子覆盖。这至少可以帮助您确保不会意外地将字段放在您不想编辑的页面上。

答案 1 :(得分:1)

如果您不希望字段可编辑,为什么首先要在编辑表单中对其进行编辑?使用两个单独的视图模型。一个用于显示所有必要数据的GET请求。只读数据只是文本/标签。第二个视图模型将用于POST / PUT请求,您只传递可编辑的数据。

如果您需要一些数据进行往返,您可以将它们放置到隐藏字段并使用带有哈希的第二个隐藏字段。您可以像(伪代码)那样获取哈希:

ComputeSHA1(dataValue.ToString() + salt);

盐只是您的应用所知的秘密价值。当数据往返您的应用程序时,您将再次计算哈希值(您必须使用相同的盐)并将其与请求中存储的哈希值进行比较。如果这两者不同,则用户试图操纵那些隐藏的字段。

答案 2 :(得分:0)

不是为您的基本模型实现编辑操作,而是为了编辑所有字段,而是创建一个仅包含您想要编辑的字段的单独模型。这种ViewModel方法更安全,并且避免了必须始终指定属性列表的问题,例如在白名单/黑名单方法中。

有关详细信息,请参阅此处:How to Preserve/Protect Certain Fields in Edit in ASP.NET MVC

答案 3 :(得分:0)

您可以通过在Model类的顶部添加字段来防止字段被HTTP(又名用户)修改。

using namespace std;
template<typename T, typename PredT>
void foo(PredT pred)
{
    for(size_t i=0; i< 3; i++)
    {
        std::function<void(T)> predImpl(pred);
        T t{};
        predImpl(t);
    }
}


template<typename T>
void foo2(std::function<void(T)> func)
{
    for(size_t i=0; i< 3; i++)
    {
        T t{}; //there's obviously other logic that produces those;
        func(t);
    }
}

int main()
{     
    //foo([](int x) {cout << x << '\n';}); //error: no matching function for call to 'foo(main()::<lambda(int)>)
    // foo([](int x) {cout << x << '\n';}); doesn't work  error: no matching function for call to 'foo(main()::<lambda(int)>)' 
    foo2(std::function<void(int)>([](int x) {cout << x << '\n';})); // syntax is ugly, requires an explicit conversion to std::function

}