Question

J'ai un projet REST WCF 4.0 basé sur le service de WCF REST Modèle 40 (CS). Je voudrais exposer les URL simples de point de terminaison de service sans barres obliques arrière. Par exemple:

  1. CarService.cs
  2. TruckService.cs

Je regarde les URL ci-dessus que les demandes de ressources (pas de dossiers), ce qui est la raison pour laquelle je ne pense pas que des barres obliques de suivi sont ici appropriés.

Malheureusement, je ne peux pas sembler obtenir le comportement que je veux parce que je suis toujours redirigée vers / voitures / et / camions / avec un slash.

Voici comment j'ai défini la route « voitures » et méthode de service - Notez que je n'ai pas inclus des barres obliques dans une de la route ou des définitions de modèle URI:

// Global.asax.cs
RouteTable.Routes.Add(new ServiceRoute("cars", new WebServiceHostFactory(), typeof(CarService)));

// CarService.cs
[WebGet(UriTemplate = "")]
public List<Car> GetCollection()
{
    return DataContext.GetAllCars();
}

Notez que MVC ne fonctionne pas de cette façon. Avec la méthode MapRoute je peux acheminer les demandes directement à http://www.domain.com/about sans redirection vers / à propos / . Comment puis-je obtenir le même comportement dans WCF REST 4.0?

Était-ce utile?

La solution

Le principal problème que vous utilisez en est que le version actuelle des causes WCF REST une 307 redirect (à la « / ») lorsque vous avez une chaîne vide pour la UriTemplate dans votre WebGet attribut. Pour autant que je sache, il n'y a pas de se déplacer cela dans la version actuelle.

Cependant, il y a quelques solution « intermédiaire » à votre problème étant donné que vous voulez une solution 1) vous permet de différencier les services et 2) ont (relativement) courtes URIs.

Première solution Vous pouvez mettre dans votre fichier global.asax (par cet exemple ). Vous pouvez faire une route de service pour chaque service:

RouteTable.Routes.Add(new ServiceRoute("cars", new WebServiceHostFactory(), typeof(CarService)));
RouteTable.Routes.Add(new ServiceRoute("trucks", new WebServiceHostFactory(), typeof(TruckService)));

À ce stade, vous pouvez remplir votre UriTemplate dans chaque service:

[WebGet(UriTemplate = "all")]
CarPool GetAllCars();

[WebGet(UriTemplate = "{carName}")]
Car GetCar(string carName);

Cela vous permettra de Uris:

www.domain.com/cars/all
www.domain.com/cars/123 or www.domain.com/cars/honda

De même pour les camions:

www.domain.com/trucks/all
www.domain.com/trucks/123 or www.domain.com/trucks/ford

Deuxième solution Utilisez l'hôte de service de la (c.-à-la WebServiceHost2Factory) REST Starter Kit de.

RouteTable.Routes.Add(new ServiceRoute("cars", new WebServiceHost2Factory(), typeof(CarService)));

Cela ne donne pas lieu à une 307 redirect lorsque vous utilisez les URIs que vous essayez d'utiliser ci-dessus et donc, vous donne exactement ce dont vous avez besoin. Bien que je me rends compte que ça fait un peu bizarre en utilisant cette usine d'accueil de service plutôt que celui qui est livré avec 4 WCF.

Autres conseils

Vous avez besoin d'un UriTemplate, Essayez quelque chose comme ceci:

 [ServiceContract()]
 public interface ICarService
 {

     [OperationContract]
     [WebGet(UriTemplate = "/Car")]
     CarPool GetAllCars();

     [OperationContract]
     [WebGet(UriTemplate = "/Car/{carName}")]
     Car GetCar(string carName);

 }

Essayez de mettre cela dans le Global.asax.cs

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string rawUrl = HttpContext.Current.Request.RawUrl.ToLower();

        if (rawUrl.EndsWith("/cars"))
        {
            HttpContext.Current.RewritePath(rawUrl + "/");  // append trailing slash
        }
    }

question plus ancien, mais voici comment je l'ai résolu le problème avec un service REST WCF4 (en utilisant le RouteTable dans Global.asax ajouter ServiceRoutes). IIS7 est configuré de telle sorte qu'au moment où le service est appelé j'ai un chemin relatif vide de sorte que le UriTemplate de méthode de gestion est vide comme l'exemple de voiture de Will. J'ai utilisé une règle de réécriture dans le fichier web.config du service pour ajouter un « / » si nécessaire. Il correspond toujours le chemin vérifie ensuite l'original URI ({REQUEST_URI}) pour voir si elle contient un chemin sans fuite « /".

    <rewrite>
        <rules>
            <!--
            This rule will append a "/" after "/car" if
            the client makes a request without a trailing "/".
            ASP however must have a trailing "/" to find
            the right handler.
            -->
            <rule name="FixCarPath" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{REQUEST_URI}" pattern="/car\?" />
                </conditions>
                <action type="Rewrite" url="{PATH_INFO}/" />
            </rule>
        </rules>
    </rewrite>

Un peu plus réutilisable:

public class Global : NinjectHttpApplication
{

    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();
        RegisterRoutes();
    }

    private void RegisterRoutes()
    {
        RouteTable.Routes.Add(new ServiceRoute("login", new NinjectWebServiceHostFactory(), typeof(LoginService)));
        RouteTable.Routes.Add(new ServiceRoute("incidents", new NinjectWebServiceHostFactory(), typeof(IncidentService)));
        SetRoutePrefixes();
    }
    //This is a workaround for WCF forcing you to end with "/" if you dont have a urlTemplate and redirecting if you dont have
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string rawUrl = HttpContext.Current.Request.RawUrl.ToLower();


        if (_routePrefixes.Any(rawUrl.EndsWith))
        {
            HttpContext.Current.RewritePath(rawUrl + "/");  // append trailing slash
        }
    }


    private static List<string> _routePrefixes; 
    private static void SetRoutePrefixes()
    {
        _routePrefixes = new List<string>();
        foreach (var route in RouteTable.Routes)
        {
            var r = route as Route;
            var routePrefix = r.Url.Split('/').First();
            _routePrefixes.Add(routePrefix);
        }
    }

Essayez de changer votre code dans le Global.asax de ...

Routes.Add(new ServiceRoute("cars", new WebServiceHostFactory(), typeof(CarService))); RouteTable.Routes.Add(new ServiceRoute("trucks", new WebServiceHostFactory(), typeof(TruckService)));

... à ...

WebServiceHostFactory factory = new WebServiceHostFactory();

Routes.Add(new ServiceRoute("cars", factory, typeof(CarService))); RouteTable.Routes.Add(new ServiceRoute("trucks", factory, typeof(TruckService)));

scroll top