簡體   English   中英

ASP.NET MVC 模型在表單元素名稱中使用破折號進行綁定

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

我一直在互聯網上搜索,試圖找到一種方法來將我的表單元素中的破折號容納到 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" />

想法?

您始終可以創建自己的模型活頁夾。

下面是一個實現支持向模型屬性添加別名的活頁夾的示例:

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...
}

編輯:正如博主所說,此實現基於安德拉斯對以下 SO 問題的回答: Asp.Net MVC 2 - Bind a model's property to a different named value

通過創建自定義表單值提供程序,您可以輕松解決此問題。 另一個優點是您可以通過裝飾自定義屬性來避免污染所有模型屬性。

自定義表單值提供程序

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();
    }
}

價值提供者工廠

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

        return new DashFormValueProvider(controllerContext);
    }
}

全局.asax.cs

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

對於尋找 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://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