简体   繁体   English

ASP.NET MVC 模型在表单元素名称中使用破折号进行绑定

[英]ASP.NET MVC Model Binding with Dashes in Form Element Names

I have been scouring the internet trying to find a way to accomodate dashes from my form elements into the default model binding behavior of ASP.NET's Controllers in MVC 2, 3, or even 4.我一直在互联网上搜索,试图找到一种方法来将我的表单元素中的破折号容纳到 MVC 2、3 甚至 4 中 ASP.NET 控制器的默认模型绑定行为中。

As a front-end developer, I prefer dashes in my CSS over camelCase or underscores.作为一名前端开发人员,我更喜欢 CSS 中的破折号,而不是驼峰式命名法或下划线。 In my markup, what I want to be able to do to is something like this:在我的标记中,我希望能够做的是这样的:

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

In the controller, I would be passing in a C# object that would look like this:在控制器中,我将传递一个如下所示的 C# 对象:

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

Is there some way to extend the Controller class to accommodate this through some regex or other behavior?有没有办法通过一些正则表达式或其他行为来扩展Controller类以适应这种情况? I hate the fact that I have to do something like this:我讨厌我必须做这样的事情:

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

or even this:甚至这个:

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

Thoughts?想法?

You could always create your own model binder.您始终可以创建自己的模型活页夹。

Here's an example that implements a binder that supports adding Aliases to model properties:下面是一个实现支持向模型属性添加别名的活页夹的示例:

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

And with it do something like:并用它做类似的事情:

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

EDIT: This implementation, as the blogger says, is based on Andras' answer on the following SO question: Asp.Net MVC 2 - Bind a model's property to a different named value编辑:正如博主所说,此实现基于安德拉斯对以下 SO 问题的回答: Asp.Net MVC 2 - Bind a model's property to a different named value

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全局.asax.cs

ValueProviderFactories.Factories.Add(new DashFormValueProviderFactory());

For readers looking for an ASP.NET Core solution, try one of the [From...] attributes.对于寻找 ASP.NET Core 解决方案的读者,请尝试[From...]属性之一。 For example:例如:

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

The [From...] attributes are briefly described at https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#sources . [From...]属性在https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#sources中进行了简要描述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM