ASP.NET Web窗体中的ASMX Web服务路由 [英] ASMX web services routing in ASP.NET Web Forms

查看:175
本文介绍了ASP.NET Web窗体中的ASMX Web服务路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


注意:该代码中没有MVC。纯旧的Web表单和 .asmx Web服务。

NOTE: There is no MVC in this code. Pure old Web Forms and .asmx Web Service.

我继承了大型ASP.NET Web表单和我的新公司的Web Service( .asmx )应用程序。

I have inherited a large scale ASP.NET Web Forms & Web Service (.asmx) application at my new company.

由于某些需要,我尝试使用URL

Due to some need I am trying to do URL Routing for all Web Forms, which I was successfully able to do.

现在为 .asmx routes.MapPageRoute 不起作用。根据下面的文章,我创建了一个 IRouteHandler 类。代码如下:

Now for .asmx, routes.MapPageRoute does not work. Based on the below article, I created an IRouteHandler class. Here's how the code looks:

using System;
using System.Web;
using System.Web.Routing;
using System.Web.Services.Protocols;
using System.Collections.Generic;
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));
}

}

http://mikeoncode.blogspot.in/2014/09/aspnet-web- form-routing-for-web.html

现在,当我通过 Global.asax 进行路由时,它适用于根文档文件,但不适用于 .asmx 文件中的Web方法。

Now when I do routing via Global.asax, it work for the root documentation file but does not work with the Web Methods inside my .asmx files.

 routes.Add("myservice", new System.Web.Routing.Route("service/sDxcdfG3SC", new System.Web.Routing.RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler("~/service/myoriginal.asmx")));

    routes.MapPageRoute("", "service/sDxcdfG3SC", "~/service/myoriginal.asmx");



目标



我想映射一个 .asmx Web方法URL,例如 www.website.com/service/myservice.asmx/fetchdata 到一个URL带有.NET路由的名称中带有 www.website.com/service/ldfdsfsdf/dsd3dfd3d 的名称。

Goal

I would like to map an .asmx Web Method URL such as www.website.com/service/myservice.asmx/fetchdata to a URL with obscured names in it like www.website.com/service/ldfdsfsdf/dsd3dfd3d using .NET Routing.

推荐答案

通过路由进行此操作比在您发布的文章中稍微棘手,因为您没有不想传入的URL具有查询字符串参数,并且在没有?op = Method <的情况下, WebServiceHandler 不会调用该方法? / code>参数。

It is slightly more tricky to do this with routing than in the article you posted because you don't want the incoming URL to have a query string parameter and it looks like the WebServiceHandler won't call the method without an ?op=Method parameter.

因此,有以下几个部分:

So, there are a few parts to this:


  1. 用于URL重写以添加?op = Method 参数的自定义路由( ServiceRoute

  2. 一个 IRouteHandler 来包装调用Web服务的 WebServiceHandlerFactory

  3. 一组ex使注册容易的紧张方法。

  1. A custom route (ServiceRoute) to do URL rewriting to add the ?op=Method parameter
  2. An IRouteHandler to wrap the WebServiceHandlerFactory that calls the web service.
  3. A set of extension methods to make registration easy.



ServiceRoute



ServiceRoute

public class ServiceRoute : Route
{
    public ServiceRoute(string url, string virtualPath, RouteValueDictionary defaults, RouteValueDictionary constraints)
        : base(url, defaults, constraints, new ServiceRouteHandler(virtualPath))
    {
        this.VirtualPath = virtualPath;
    }

    public string VirtualPath { get; private set; }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        // Run a test to see if the URL and constraints don't match
        // (will be null) and reject the request if they don't.
        if (base.GetRouteData(httpContext) == null)
            return null;

        // Use URL rewriting to fake the query string for the ASMX
        httpContext.RewritePath(this.VirtualPath);

        return base.GetRouteData(httpContext);
    }
}



ServiceHandler



ServiceHandler

public class ServiceRouteHandler : IRouteHandler
{
    private readonly string virtualPath;
    private readonly WebServiceHandlerFactory handlerFactory = new WebServiceHandlerFactory();

    public ServiceRouteHandler(string virtualPath)
    {
        if (virtualPath == null)
            throw new ArgumentNullException(nameof(virtualPath));
        if (!virtualPath.StartsWith("~/"))
            throw new ArgumentException("Virtual path must start with ~/", "virtualPath");
        this.virtualPath = virtualPath;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // Strip the query string (if any) off of the file path
        string filePath = virtualPath;
        int qIndex = filePath.IndexOf('?');
        if (qIndex >= 0)
            filePath = filePath.Substring(0, qIndex);

        // Note: can't pass requestContext.HttpContext as the first 
        // parameter because that's type HttpContextBase, while 
        // GetHandler expects HttpContext.
        return handlerFactory.GetHandler(
            HttpContext.Current, 
            requestContext.HttpContext.Request.HttpMethod,
            virtualPath, 
            requestContext.HttpContext.Server.MapPath(filePath));
    }
}



RouteCollectionExtensions



RouteCollectionExtensions

public static class RouteCollectionExtensions
{
    public static void MapServiceRoutes(
        this RouteCollection routes,
        Dictionary<string, string> urlToVirtualPathMap,
        object defaults = null,
        object constraints = null)
    {
        foreach (var kvp in urlToVirtualPathMap)
            MapServiceRoute(routes, null, kvp.Key, kvp.Value, defaults, constraints);
    }

    public static Route MapServiceRoute(
        this RouteCollection routes, 
        string url, 
        string virtualPath, 
        object defaults = null, 
        object constraints = null)
    {
        return MapServiceRoute(routes, null, url, virtualPath, defaults, constraints);
    }

    public static Route MapServiceRoute(
        this RouteCollection routes, 
        string routeName, 
        string url, 
        string virtualPath, 
        object defaults = null, 
        object constraints = null)
    {
        if (routes == null)
            throw new ArgumentNullException("routes");

        Route route = new ServiceRoute(
            url: url,
            virtualPath: virtualPath,
            defaults: new RouteValueDictionary(defaults) { { "controller", null }, { "action", null } },
            constraints: new RouteValueDictionary(constraints)
        );
        routes.Add(routeName, route);
        return route;
    }
}



用法



您可以使用 MapServiceRoute 一次添加一条路线(带有可选名称):

Usage

You can either use MapServiceRoute to add the routes one at a time (with an optional name):

public static class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var settings = new FriendlyUrlSettings();
        settings.AutoRedirectMode = RedirectMode.Permanent;
        routes.EnableFriendlyUrls(settings);

        routes.MapServiceRoute("AddRoute", "service/ldfdsfsdf/dsd3dfd3d", "~/service/myoriginal.asmx?op=Add");
        routes.MapServiceRoute("SubtractRoute", "service/ldfdsfsdf/dsd3dfd3g", "~/service/myoriginal.asmx?op=Subtract");
        routes.MapServiceRoute("MultiplyRoute", "service/ldfdsfsdf/dsd3dfd3k", "~/service/myoriginal.asmx?op=Multiply");
        routes.MapServiceRoute("DivideRoute", "service/ldfdsfsdf/dsd3dfd3v", "~/service/myoriginal.asmx?op=Divide");
    }
}

或者,您可以拨打 MapServiceRoutes 一次映射一批Web服务路由:

Alternatively, you can call MapServiceRoutes to map a batch of your web service routes at once:

public static class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var settings = new FriendlyUrlSettings();
        settings.AutoRedirectMode = RedirectMode.Permanent;
        routes.EnableFriendlyUrls(settings);

        routes.MapServiceRoutes(new Dictionary<string, string>
        {
            { "service/ldfdsfsdf/dsd3dfd3d", "~/service/myoriginal.asmx?op=Add" },
            { "service/ldfdsfsdf/dsd3dfd3g", "~/service/myoriginal.asmx?op=Subtract" },
            { "service/ldfdsfsdf/dsd3dfd3k", "~/service/myoriginal.asmx?op=Multiply" },
            { "service/ldfdsfsdf/dsd3dfd3v", "~/service/myoriginal.asmx?op=Divide" },
        });
    }
}




注意::如果您要在应用程序中使用MVC,通常应该在这些路由之后 之后注册您的MVC路由。

NOTE: If you were to have MVC in the application, you should generally register your MVC routes after these routes.

参考:

  • Creating a route for a .asmx Web Service with ASP.NET routing
  • .NET 4 URL Routing for Web Services (asmx)

这篇关于ASP.NET Web窗体中的ASMX Web服务路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆