13

我一直在互联网上搜索,试图找到一种方法来将我的表单元素中的破折号容纳到 MVC 2、3 甚至 4 中 ASP.NET 控制器的默认模型绑定行为中。

作为一名前端开发人员,我更喜欢 CSS 中的破折号,而不是驼峰式或下划线。在我的标记中,我想要做的是这样的:

<input type="text" name="first-name" class="required" />
<input type="text" name="last-name" class="required" />

在控制器中,我将传入一个如下所示的 C# 对象:

public class Person
{
      public string FirstName { get; set; }
      public string LastName { get; set; }
      //etc...
}

有没有办法通过一些正则表达式或其他行为来扩展Controller类以适应这种情况?我讨厌我必须做这样的事情:

<input type="text" name="person.firstname" class="required" />

甚至这个:

<input type="text" name="isPersonAttending" class="required" />

想法?

4

3 回答 3

7

您始终可以创建自己的模型活页夹。

这是一个实现支持将别名添加到模型属性的活页夹的示例:

http://ole.michelsen.dk/blog/bind-a-model-property-to-a-different-named-query-string-field/

并使用它执行以下操作:

[ModelBinder(typeof(AliasModelBinder))]
public class Person
{
      [BindAlias("first-name")]
      public string FirstName { get; set; }
      [BindAlias("last-name")]
      public string LastName { get; set; }
      //etc...
}

编辑: 正如博主所说,此实现基于 Andras 对以下 SO 问题的回答: Asp.Net MVC 2 - Bind a model's property to a different named value

于 2012-06-23T22:36:32.287 回答
3

By creating a custom form value provider you could solve this problem easily. The other advantage is you can avoid polluting all the model properties by decorating custom attributes.

Custom Form Value Provider

public class DashFormValueProvider : NameValueCollectionValueProvider
{
    public DashFormValueProvider(ControllerContext controllerContext)
    : base(controllerContext.HttpContext.Request.Form, 
    controllerContext.HttpContext.Request.Unvalidated().Form, 
    CultureInfo.CurrentCulture)
    {
    }

    public override bool ContainsPrefix(string prefix)
    {
        return base.ContainsPrefix(GetModifiedPrefix(prefix));
    }

    public override ValueProviderResult GetValue(string key)
    {
        return base.GetValue(GetModifiedPrefix(key));
    }

    public override ValueProviderResult GetValue(string key, bool skipValidation)
    {
        return base.GetValue(GetModifiedPrefix(key), skipValidation);
    }

    // this will convert the key "FirstName" to "first-name".
    private string GetModifiedPrefix(string prefix)
    {
        return Regex.Replace(prefix, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1-").ToLower();
    }
}

Value Provider Factory

public class DashFormValueProviderFactory : ValueProviderFactory
{
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }

        return new DashFormValueProvider(controllerContext);
    }
}

Global.asax.cs

ValueProviderFactories.Factories.Add(new DashFormValueProviderFactory());
于 2012-06-24T06:30:19.523 回答
2

对于寻找 ASP.NET Core 解决方案的读者,请尝试其中一个[From...]属性。例如:

public class Person
{
    [FromForm(Name = "first-name")]
    public string FirstName { get; set; }
    [FromForm(Name = "last-name")]
    public string LastName { get; set; }
    //etc...
}

这些[From...]属性在https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#sources进行了简要描述。

于 2020-04-16T16:24:47.890 回答