0

这样我可以为隐藏字段编写自定义助手

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Linq.Expressions;

namespace CustomHtmlHelpers.CustomHelpers
{
    public static class CustomHiddenHelperModelBinding
    {
        //This overload accepts single expression as parameter.
        public static MvcHtmlString Custom_HiddenFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            return Custom_HiddenFor(helper, expression, null);
        }

        //This overload accepts expression and htmlAttributes object as parameter.
        public static MvcHtmlString Custom_HiddenFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
        {
            //Fetching the metadata related to expression. This includes name of the property, model value of the property as well.
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            //Fetching the property name.
            string propertyName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

            //Creating a textarea tag using TagBuilder class.
            TagBuilder hidden = new TagBuilder("input");

            //Setting the type attribute to hidden to render hidden input field.
            hidden.Attributes.Add("type", "hidden");

            //Setting the name and id attribute.
            hidden.Attributes.Add("name", propertyName);
            hidden.Attributes.Add("id", propertyName);

            //Setting the value attribute of textbox with model value if present.
            if (metadata.Model != null)
            {
                hidden.Attributes.Add("value", metadata.Model.ToString());
            }
            //merging any htmlAttributes passed.
            hidden.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            return MvcHtmlString.Create(hidden.ToString(TagRenderMode.Normal));
        }
    }
}

稍后我们可以像访问它一样

@Html.Custom_HiddenFor(Model => Model.hidden)
@Html.Custom_HiddenFor(Model => Model.hidden, new { @class = "hiddenClass" })

我为隐藏字段重写自己的 html 帮助程序的目标是在客户端将值呈现为加密文本以及防篡改。如果有人篡改数据,那么我想在服务器端检查,如果篡改,我将向用户显示友好的错误消息。

这是另一个使用机器密钥加密的示例代码,但我不确定该代码在部分信任环境中是否正常工作?

这是示例代码

string Protect(byte[] data)
{
    if (data == null || data.Length == 0) return null;
    return MachineKey.Encode(data, MachineKeyProtection.All);
}

byte[] Unprotect(string value)
{
    if (String.IsNullOrWhiteSpace(value)) return null;
    return MachineKey.Decode(value, MachineKeyProtection.All);
}


 here’s the 4.5 usage (it supports a slightly more sophisticated usage)
 -------------------------------------------------------------------------
 const string MachineKeyPurpose = "MyApp:Username:{0}";
 const string Anonymous = "<anonymous>";

 string GetMachineKeyPurpose(IPrincipal user)
 {
     return String.Format(MachineKeyPurpose,
         user.Identity.IsAuthenticated ? user.Identity.Name : Anonymous);
 }

 string Protect(byte[] data)
 {
     if (data == null || data.Length == 0) return null;
     var purpose = GetMachineKeyPurpose(Thread.CurrentPrincipal);
     var value = MachineKey.Protect(data, purpose);
     return Convert.ToBase64String(value);
 }

 byte[] Unprotect(string value)
 {
     if (String.IsNullOrWhiteSpace(value)) return null;
     var purpose = GetMachineKeyPurpose(Thread.CurrentPrincipal);
     var bytes = Convert.FromBase64String(value);
     return MachineKey.Unprotect(bytes, purpose);
}

另一种加密方式

To generate a random string, use the RNGCryptoServiceProvider.

public string GenerateSalt(int length)
{
    var rng = new RNGCryptoServiceProvider();
    var buffer = new byte[length];
    rng.GetBytes(buffer);
    return Convert.ToBase64String(buffer);
}

现在我们可以使用下面的函数生成一个哈希密码

public virtual string CreatePasswordHash(string password, string saltkey, string passwordFormat = "SHA1")
{
    if (String.IsNullOrEmpty(passwordFormat))
        passwordFormat = "SHA1";
    string saltAndPassword = String.Concat(password, saltkey);
    string hashedPassword =
        FormsAuthentication.HashPasswordForStoringInConfigFile(
            saltAndPassword, passwordFormat);
    return hashedPassword;
}

所以请指导我如何重写我自己的自定义 html 帮助程序,它将以最安全的方式加密数据,然后可以检查以确保客户端的值是否被篡改。

我还有另一个要求是在表单发布和调用操作方法时轻松解密该值。我想使用操作方法上的属性解密加密值。我想触发一个函数将在操作方法之前触发并在数据反序列化为模型或操作方法参数之前解密值。

可能吗 ?

我希望我的操作方法看起来像

 [HttpPost]
 [Decrypt]
 public ActionResult Save(string personname, string email)
 {
       return View();
 }

 or

 [HttpPost]
 [Decrypt]
 public ActionResult Save(Person oPerson)
 {
        return View();
 }

我希望我的 [Decrypt] 属性将在调用操作方法 Save 之前触发方法调用 decypt 并将所有值传递给 decypt() 函数。如果 decypt() 函数找到任何加密值,那么它将解密和反序列化解密值以模型或操作方法参数。

所以我有三个要求


1)我想编写一个自定义的 html 助手,它将呈现具有加密值的隐藏字段。

2)当数据发布到服务器时,我可以检测到该值是否被篡改。如果篡改,则会向用户显示带有正确消息的错误页面。

3)动作方法将具有自定义属性,该属性将在动作方法执行之前调用一个函数。如果找到任何加密值,该函数将解密值。解密后,解密的值将正确地反序列化为模型或其他操作方法参数。

我是 MVC 的新手。所以请指导我如何继续使用示例代码。谢谢

4

1 回答 1

2

怎么样@Html.AntiForgeryToken()

“生成一个隐藏的表单字段(防伪令牌),在提交表单时进行验证。” 开发者网络

示例: 1. 在您的标记中添加@Html.AntiForgeryToken()到表单。2.添加[ValidateAntiForgeryToken]属性你的控制器动作。

开发者网络

于 2013-09-23T15:51:26.033 回答