首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET MVC Model 繫結機制模擬實作:陣列型別綁定

     編輯:關於ASP.NET

陣列繫結兩大來源

  1. 同名多值:表單多個同名 input,ValueProvider 回傳字串陣列,ConvertTo(int[]) 自動轉型。
  2. 索引式:鍵格式 prefix[0]、prefix[1]...,逐一繫結元素。

NameValueCollectionValueProvider 多值行為

var data = new NameValueCollection();
data.Add("foo", "123");
data.Add("foo", "456");
data.Add("foo", "789");
var provider = new NameValueCollectionValueProvider(data, CultureInfo.InvariantCulture);

var result = provider.GetValue("foo");
result.RawValue;           // string[] { "123", "456", "789" }
result.ConvertTo(typeof(int[])); // int[] { 123, 456, 789 }
result.ConvertTo(typeof(int));   // 123 (僅取第一個)

模擬繫結器擴充:BindArrayModel

public class DefaultModelBinder
{
    public object BindModel(Type parameterType, string prefix)
    {
        if (!ValueProvider.ContainsPrefix(prefix)) return null;
        var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, parameterType);
        if (!metadata.IsComplexType) return ValueProvider.GetValue(prefix).ConvertTo(parameterType);
        if (parameterType.IsArray) return BindArrayModel(parameterType, prefix);
        // ... 複雜型別邏輯
    }

    private object BindArrayModel(Type parameterType, string prefix)
    {
        var list = new List<object>();
        // 1. 同名多值直接轉換
        if (ValueProvider.ContainsPrefix(prefix))
        {
            var enumerable = ValueProvider.GetValue(prefix).ConvertTo(parameterType) as IEnumerable;
            if (enumerable != null) foreach (var v in enumerable) list.Add(v);
        }
        // 2. 索引式繫結(陣列通常不支援索引式?實際上 MVC 支援)
        // 這裡簡化:若上述已取得值則不再索引式繫結
        var array = Array.CreateInstance(parameterType.GetElementType(), list.Count);
        list.CopyTo(array, 0);
        return array;
    }
}

表單對應範例

<input name="Foo" type="text" /> <!-- 三個同名 -->
<input name="Foo" type="text" />
<input name="Foo" type="text" />
<input name="Bar" type="file" /> <!-- 三個檔案 -->
<input name="Bar" type="file" />
<input name="Bar" type="file" />

Action:

public void ActionMethod(string[] foo, HttpPostedFileBase[] bar) { ... }

foo 繫結三個字串,bar 繫結三個上傳檔案。

HttpFileCollectionValueProvider 行為

繼承 DictionaryValueProvider<HttpPostedFileBase[]>,鍵為 input name,值為同名檔案陣列,完美支援多檔上傳繫結。

總結

陣列繫結核心在於 NameValueCollectionValueProvider 的多值轉換特性。模擬繫結器只需處理「同名多值直接轉換」即涵蓋 90% 情境,索引式繫結在集合/字典更常見。理解此機制可正確設計表單欄位名稱對應 Action 參數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved