[英]Mapping to an ASMX service using routing in ASP.NET MVC
我想知道是否有任何方法可以將URL映射到ASMX服務,就像處理頁面一樣(使用routes.MapPageRoute()
方法)。
當我嘗試簡單地通過將MapPageRoute指向我的服務來執行此操作時,出現錯誤
類型'MvcApplication1.Services.EchoService'不繼承自'System.Web.UI.Page'。
馬蒂亞斯。
我偶然發現了這個問題,試圖自己找到答案,由於我確實找到了解決問題的方法,所以我想我會回答。
我之所以需要它,是因為我正在將一個舊的ASP.NET網站轉換為ASP.NET MVC,並且出於兼容性目的,我需要在特定URL上可用的Web服務。 但是,該URL的路徑現在由新站點中的Controller處理,因此我無法使用具有相同名稱的物理目錄(因為這將阻止針對該URL而不是Web服務的其他URL調用控制器。 )。
PageRouteHandler
, PageRouteHandler
使用的RouteCollection.MapPageRoute
要求目標路徑的處理程序派生自System.Web.Page
,而Web服務並非如此。 因此,必須創建一個自定義頁面處理程序:
using System;
using System.Web;
using System.Web.Routing;
using System.Web.Services.Protocols;
public class ServiceRouteHandler : IRouteHandler
{
private readonly string _virtualPath;
private readonly WebServiceHandlerFactory _handlerFactory = new WebServiceHandlerFactory();
public ServiceRouteHandler(string virtualPath)
{
if( virtualPath == null )
throw new ArgumentNullException("virtualPath");
if( !virtualPath.StartsWith("~/") )
throw new ArgumentException("Virtual path must start with ~/", "virtualPath");
_virtualPath = virtualPath;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// Note: can't pass requestContext.HttpContext as the first parameter because that's
// type HttpContextBase, while GetHandler wants HttpContext.
return _handlerFactory.GetHandler(HttpContext.Current, requestContext.HttpContext.Request.HttpMethod, _virtualPath, requestContext.HttpContext.Server.MapPath(_virtualPath));
}
}
該路由處理程序將基於請求和服務的映射虛擬路徑為Web服務創建適當的處理程序。
您現在可以為Web服務添加路由,如下所示:
routes.Add("RouteName", new Route("path/to/your/service", new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler("~/actualservice.asmx")));
注意:您必須在路由值字典中指定控制器和操作值(即使它們設置為null),否則Html.ActionLink
幫助器將始終對每個單個鏈接使用此路由(除非在列表中找到匹配項)在此路線之前)。 由於您可能想在默認的MVC路由之前添加此路由,因此不要以這種方式進行匹配很重要。
當然,您可以創建自己的擴展方法來減輕此任務:
public static Route MapServiceRoute(this RouteCollection routes, string routeName, string url, string virtualPath)
{
if( routes == null )
throw new ArgumentNullException("routes");
Route route = new Route(url, new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler(virtualPath));
routes.Add(routeName, route);
return route;
}
之后,您可以簡單地執行以下操作:
routes.MapServiceRoute("RouteName", "path/to/your/service", "~/actualservice.asmx");
我希望這可以幫助某人,盡管這個問題已經存在了很長時間。 :)
現在,我們已經花了兩年的時間,如何使用Web API呢? :)
編輯:開玩笑,如果那對您不起作用,您仍然需要一個答案,請發表評論,我將看看是否無法提出更好的建議。
我嘗試了原始帖子的解決方案( 也在此處發布 ),但是遇到了一個嚴重的問題。 我無法在Web服務中定位Web方法。 嘗試這樣做時,出現異常,指出文件不存在。
如果您確實希望將MVC路由映射到.ASMX Web服務,請在此處說明解決方案。
我認為該解決方案通過濫用內置類型來解決問題,因為它使用反射繞過內置.NET類型的有意限制性訪問成員。
這是我采用的方法,我相信它會更簡單。
首先,您應該在.ASMX文件中設計Web服務,以便所有Web服務都充當已發布的界面。 那時我們不需要直接針對.ASMX Web服務的方法。 重要的代碼已在與應用程序的入口點無關的核心類中重新使用。 無論如何,我們都需要這樣做,以便我們可以運行自動化測試!
用具有自定義路由處理程序和http處理程序的新路由替換MVC的Web服務方法。
舊路線:
routes.MapRoute(
"Lead",
"lead/{action}.mvc",
new { controller = "Lead" });
新路線:
var dict = new RouteValueDictionary
{
{ "controller", null },
{ "action", null }
};
var handler = new LeadRouteHandler();
var route = new Route("lead/MVC_General.mvc", dict, handler);
routes.Add("Lead", route);
請注意,新路由的動作已硬編碼為“ MVC_General”。 這是因為我希望改進巨型控制器類,並為每個操作創建一個處理程序,這樣我就可以擁有一個小型類,並對每個Web方法負責。
IRouteHandler:
public class LeadRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new LeadHttpHandler();
}
}
IHttpHandler:
public class LeadHttpHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
// Just enough code to preserve the route's json interface for tests
var typedResult = new PsaLeadSubmissionResult();
typedResult.Registered = false;
typedResult.Message = new List<string>
{
"Not Implemented"
};
var jsonResult = JsonConvert.SerializeObject(typedResult);
context.Response.Write(jsonResult);
}
}
從IHttpHandler的ProcessRequest方法中,我們可以完全控制該路由的操作。 通過精心設計的Web服務體系結構,我們要做的就是調用支持您嘗試將路由映射到的.ASMX Web方法的類。
結果是一個非常干凈的Global.asax文件。 僅通過手動檢查URL,我們就可以在沒有URL路由的情況下完成所有這些工作,但這對文件來說實在是太重要了,以至於無法膨脹。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.