首先,需要了解下這篇博文:《ASP.NET WebForms MapPageRoute 路由配置》
之前,在 ASP.NET MVC 中混搭 ASP.NET WebForms,使用 MapPageRoute 沒有出現什么問題,但是今天在測試一個表單提交的時候,卻莫名其妙的出現一個詭異的問題,我先大致描述下,就是 MVC View 中使用表單,Html.BeginForm 方法提交到指定控制器的 Action 中進行處理,大致代碼為:
@using (Html.BeginForm("ProfileSubmit", "Set", FormMethod.Post, new { id = "myform" }))
{
@Html.AntiForgeryToken()
<table class="info_block" cellpadding="0" cellspacing="0">
<tr>
<td class="tr_title">
姓名:
</td>
<td class="tr_content">
@Html.TextBoxFor(n => n.RealName, new { id = "txt_name", @class = "tb_m" })
</td>
</tr>
</table>
<div class="save_block">
<input type="submit" class="btn_blue" name="btnSubmit" value="保存" onclick="return UpdateProfile();" id="btn_submit">
<div class="text_red" style="height: 3em; line-height: 3em;">
<span id="lit_tip">@Model.Message</span>
</div>
</div>
}
這是我們最普遍的寫法,把表單數據提交到 Set 控制器的 ProfileSubmit Action 中進行處理,但是在提交的時候,URL 卻變成了:
http://home.cnblogs.com/job/myresume?action=ProfileSubmit&controller=Set
是不是很詭異?我明明在 Html.BeginForm 方法中指定了 Controller 和 Action,為什么沒有起作用,反而跳轉到了一個莫名其妙的 URL,根據 URL,我就查看了下路由配置,發現下面的一段配置:
routes.MapPageRoute("JobMyResume",
"job/myresume",
"~/old/job/MyResume.aspx"
);
注意,這段路由配置並不是使用的 MapRoute,而是 MapPageRoute,是配置 ASP.NET WebForms 路由的,我把這段配置注釋掉,然后就可以了,有點莫名其妙,為什么使用 Html.BeginForm 會映射到這段路由上?最后搜了大量的資料,也沒有找到相關說明,我個人覺得是 MapPageRoute 的問題,ASP.NET MVC 混搭 ASP.NET WebForms,但是在 URL 請求處理的時候,並不是很准確,凡事使用 Html Helps 里面的生成 URL 方法,都存在問題,除了 Html.BeginForm,還有我們常用到的 Html.ActionLink,但是從外部客戶端進入的請求,就沒有任何問題,最后找了一些相關解決方式,也證明了這一點,解決方式很簡單,先添加如下代碼:
public class IncomingRequestConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return routeDirection == RouteDirection.IncomingRequest;
}
}
然后 MapPageRoute 的路由配置改為:
routes.MapPageRoute("JobMyResume",
"job/myresume",
"~/old/job/MyResume.aspx", false, null, new RouteValueDictionary(new
{
controller = new IncomingRequestConstraint()
})
);
什么意思呢?RouteDirection.IncomingRequest 的意思,就是路由約束限制在外部,也就是說只請求來自客戶端的 URL,內部的 URL 不匹配此路由,像 Html.ActionLink/BeginForm 是 MVC 內部生成的 URL,所以是不被匹配的,RouteDirection 還有另外一個枚舉值 UrlGeneration,它的意思就是只請求內部生成的 URL。
上面這種解決方案,只是臨時的解決方案,也就是像打補丁一樣的處理方式,關於為什么會出現這個問題?MapPageRoute 具體是怎么進行配置的?ASP.NET MVC 混搭 ASP.NET WebForms 請求到底是怎么處理的?這些還不是很清楚,希望大家可以指教。