一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 你所不知道的ASP.NET Core進階系列(三)

你所不知道的ASP.NET Core進階系列(三)

2023-12-18 00:14未知服務器之家 ASP.NET教程

前言 一年多沒更新博客,上一次寫此系列還是四年前,雖遲但到,沒有承諾,主打隨性,所以不存在斷更,催更,哈哈,上一篇我們細究從請求到綁定詳細原理,本篇則是探討模型綁定細節,當一個問題產生到最終解決時,回過頭

前言

一年多沒更新博客,上一次寫此系列還是四年前,雖遲但到,沒有承諾,主打隨性,所以不存在斷更,催更,哈哈,上一篇我們細究從請求到綁定詳細原理,本篇則是探討模型綁定細節,當一個問題產生到最終解決時,回過頭我們整體分析其產生背景以及設計思路才能有所獲。好了,廢話不多說,我們開始模型綁定細節之旅。

問題產生

我們定義一個模型,然后進行查詢請求,當然,此時我們在后臺控制器Action方法上推薦明確使用查詢特性即FromQuery接收,代碼如下

public class UserAddress
{
    public string Code { get; set; }
}
[ApiController]
[Route("api/[controller]/[action]")]
public class UserAddressController : ControllerBase
{
    private readonly ILogger<UserAddressController> _logger;

    public UserAddressController(ILogger<UserAddressController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult Get([FromQuery] UserAddress address)
    {
        return Ok(address);
    }
}

你所不知道的ASP.NET Core進階系列(三)

你所不知道的ASP.NET Core進階系列(三)

?沒任何毛病,接下來我們在定義用戶地址類上增加一個屬性,如下所示

public class UserAddress
{
    public string Code { get; set; }
    public string Address { get; set; }
}

你所不知道的ASP.NET Core進階系列(三)

你所不知道的ASP.NET Core進階系列(三)

值綁定不上,這是神馬情況,這難道是官方的Bug嗎,我們用6.0和7.0都是如此,毫無疑問,利用.NET 8.0依然是此等結果,問題來了,請稍加思考大概是什么原因,讓我們繼續往下分析

根因源碼分析

通過前后對比我們可以初步分析到原因可能是二方面之一或者二者結合,其一,對象屬性address和接收對象參數變量address不能相同(不區分大小寫),其二,接受對象參數變量address和URL上的鍵名稱address不能相同(不區分大小寫)。我們暫且只能分析到這個地方,當然,我們一試便知,至于根因是什么,接下來我們只能去分析模型綁定源碼,說到分析源碼,可能有些童鞋不知從何開始,這里給出我們從0開始分析其根因的整個過程,以供需要的童鞋做參考哈。僅我個人看法,除非精通,否則必會經歷一個過程,這是必然,所以不用懷疑任誰都不能立馬找到大概源碼在哪里,我們注意關注點分析,別看著看著跑偏了,既然是模型綁定而且是查詢綁定,這是在了解基本原理或學習官網文檔有所印象的前提下,先看這里

你所不知道的ASP.NET Core進階系列(三)

然后我們怎么開始呢,我們直接自定義實現一個查詢字符串值綁定即將上述代碼拷貝一份出來,比如有些是有依賴的等等,將其修改去掉等等處理,還是我們強調的關注點,最后我們還要添加自定義實現

   builder.Services.AddControllers(options =>
   {
       options.ValueProviderFactories.Insert(0, new QueryStringValueProviderFactory());
   });

你所不知道的ASP.NET Core進階系列(三)

你所不知道的ASP.NET Core進階系列(三)

我們看到實際上值都已正確獲取到,但實際上傳過來的鍵應該是屬性Code或者Address才對,同時我們發現在此實現中包含了一個是否包含前綴的方法,這好像貌似就是針對我們綁定的屬性加上方法上的參數變量即address,所以我們斷點一步步調試進入該方法具體實現

你所不知道的ASP.NET Core進階系列(三)

源碼調試現在還是方便了很多,我們來到綁定源頭即將ActionContext轉換為ModelBindingContext,也就是調用具體綁定實現之前即相關參數綁定準備前夕,我們看到賦值給了模型綁定上下文中的模型名稱即ModelName,我們猜測這就是增加的前綴,繼續往下調試實際調用的綁定者是哪一個,我們看到實際使用的復雜對象綁定,框架內置實現了十幾個綁定,ValueProvider只是其中后臺接收最簡單的參數類型或者直接接收請求上下文相關的預處理,大多都由ModelBinder來接收處理綁定到控制器方法上,調試源碼并不是那么明朗,我們直接再自定義實現一個ComplexObjectModelBinderProvider,其具體ComplexObjectModelBinder有個方法BindPropertiesAsync,這是實際做相關處理的地方

你所不知道的ASP.NET Core進階系列(三)

你所不知道的ASP.NET Core進階系列(三)

/// <summary>
/// Create a property model name with a prefix.
/// </summary>
/// <param name="prefix">The prefix to use.</param>
/// <param name="propertyName">The property name.</param>
/// <returns>The property model name.</returns>
public static string CreatePropertyModelName(string? prefix, string? propertyName)
{
    if (string.IsNullOrEmpty(prefix))
    {
        return propertyName ?? string.Empty;
    }

    if (string.IsNullOrEmpty(propertyName))
    {
        return prefix ?? string.Empty;
    }

    if (propertyName.StartsWith('['))
    {
        // The propertyName might represent an indexer access, in which case combining
        // with a 'dot' would be invalid. This case occurs only when called from ValidationVisitor.
        return prefix + propertyName;
    }

    return prefix + "." + propertyName;
}

好了,到了這里我們只是知道了框架就是這么做的處理導致值綁定不上,問題又來了,請思考框架這么設計的初衷和思想是什么呢,框架為我們考慮了諸多場景。我們刪除上述所有自定義實現, 框架以為我們想要達到如下綁定目的,但沒曾想劍走偏鋒,實際被我們鉆了個空子,正所謂你以為的是你以為的并不是我以為的,然后一臉懵波

你所不知道的ASP.NET Core進階系列(三)

你所不知道的ASP.NET Core進階系列(三)

舉一反三

還沒完,繼續開課,我們分析完整個前因后果后,我們終于明白了IValueProvider接口中所說的前綴具體指的是什么意思,然后對于前綴匹配使用二分法算法,同理,我們也不難看出,上述是對象綁定處理,在相同條件下,對于集合亦是如此。

你所不知道的ASP.NET Core進階系列(三)

總結

當進行查詢操作時請求URL上的鍵名稱若和后臺接收參數變量名稱相同且不區分大小寫,框架以為我們想要使用接收參數變量作為前綴來綁定值,在相同等等條件下,對于集合亦是如此,除非我們自定義實現一套,否則我們萬不可將其定義為相同名稱,如此會導致值綁定不上。

翻譯

搜索

復制

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国色天香社区在线视频播放 | 天天曰天天干 | 国产成人亚洲精品91专区高清 | 青青国产成人久久激情91麻豆 | 国产欧美综合精品一区二区 | 日韩影院在线观看 | 精品在线小视频 | 操美女| 国产精品1024永久免费视频 | 爽好舒服把腿张小说 | 亚洲国产精品二区久久 | 麻豆网站在线观看 | 激情视频亚洲 | 日本中文字幕高清 | 草逼吧| 午夜影视免费 | av在线色| 国内老司机精品视频在线播出 | miaa076深田咏美在线 | 亚欧有色在线观看免费版高清 | 成人不卡在线 | 特黄特级高清免费视频毛片 | 91国语自产拍在线观看 | 国产成人在线综合 | ak福利午夜在线观看 | 网友自拍咪咪爱 | 国产在线看片网站 | 91tv在线 | 精品久久亚洲 | 9热在线精品视频观看 | 国产小嫩模好紧 | 欧美人体高清在线观看ggogo | 日产精品一二三四区国产 | 九九国产在线视频 | 日本精品中文字幕在线播放 | 免费我看视频在线观看 | 九九热在线观看视频 | 俺来操| 男生操女生动态图 | 亚洲人成网站在线观看青青 | 2023最新伦理片 |