通過表示式樹構造URL時忽略部分引數

2021-09-05 21:35:04 字數 1941 閱讀 8872

您的使用asp.net mvc的時候,一定遇到過使用post接受資料的action方法。例如:

public class 

homecontroller : controller

}

於是乎,客戶端只要像home/list這樣的url中post資料,這個controller便可以從請求的body中獲得keyword和page的值。為了實現這個功能,我們必須在客戶端準備乙個form,把它的action——也就是post的目標url寫為home/list。但是這個url改怎麼生成呢?按照傳統的做法,我們會使用表示式樹來構造這個url:

<%

= url.actionex(c => c.list("hello", 3)) %>

但是您會發現,上面這條語句最終生成的url是:

home/list?keywords=hello&page=3
這是因為asp.net routing在處理配置規則中沒有標明的route values時,會將它們作為query string拼接在url後面。這也是可以預料到的,因為作為form的url,我們又如何明確指定乙個引數的值呢?無論指定什麼值都是不合適的,我們必須將它們忽略掉——或者說,我們需要找一種可以表示「任意」引數的方式。

接下來的做法還是接著上次的結果繼續改進。您會發現這種做法有明顯的moq框架的影子,因為我們要使用這樣的方式來表示引數的忽略:

<%

= url.actionex(c => c.list(it.isany(), it.isany())) %>

這需要我們準備乙個簡單的it.isany方法的「結構」:

public static class 

it}

這個方法不是用來直接呼叫的,它只是作為表示式樹的一部分存在——這也再次說明,表示式樹的構造,並不意味著一定執行。表示式樹是一種表示方式,用來說明我們的「意圖」,僅此而已。

在原先的**中,我們是這樣向乙個routevaluedictionary裡填充資料的:

private static void addparametervalues(routevaluedictionary rvd, methodcallexpression call)

}

如今,call.arguments[i]可能是乙個it.any<…>()表示式,它不能直接用於求值(eval)。因此,我們要將**修改為以下這樣:

private static void addparametervalues(routevaluedictionary rvd, methodcallexpression call)

}}private static bool isparametershouldbeignored(expression arg)

我們在求值之前,需要判斷這個表示式是否是it.isany方法的呼叫。如果不是,才將其加入routevaluedictionary中。就這樣,修改結束了,總共也就10多行**的改動而已。

為了檢驗我們的成果,最好的方法進行單元測試。首先,我們準備乙個測試用的controller類和action方法:

private class 

testcontroller : controller

}

然後檢查在普通情況下,所有的route value都被正常捕獲到:

[fact]

public void get_route_values_with_arguments()

以及,如果我們想要忽略到乙個引數時,它就不會出現在routevaluedictionary中:

[fact]

public void get_route_values_with_ignored_arguements()

就這樣,我們通過表示式樹生成url的功能又前進了一小步。

表示式 表示式樹 表示式求值

總時間限制 1000ms 記憶體限制 65535kb 描述 眾所周知,任何乙個表示式,都可以用一棵表示式樹來表示。例如,表示式a b c,可以表示為如下的表示式樹 a b c 現在,給你乙個中綴表示式,這個中綴表示式用變數來表示 不含數字 請你將這個中綴表示式用表示式二叉樹的形式輸出出來。輸入輸入分...

構造一棵表示式樹

演算法分析 該演算法將字尾表示式轉變成表示式樹。由於我們已經有了將中綴表示式 轉變成字尾表示式的演算法,因此可以從這兩種輸入表示式生成表示式樹。所 描述的方法類似於字尾表示式求值的演算法。我們一次乙個符號的讀入表示式 如果符號是運算元,那麼就建立乙個單結點樹並將它推入棧中。如果符號 是操作符,他的左...

Lambda表示式表示式樹

在c 3.0中,繼匿名方法之後出現了lambda 表示式,使表達更為簡潔 快捷。lambda 表示式使用lambda 運算子 來定義,語法如下 引數列表 lambda 運算子的左邊是輸入引數,定義lambda表示式的接收引數列表,右邊包含表示式或語句塊,表示將表示式的值或語句塊返回的值傳給左邊的引數...