MVC ignoring .jpg file extension on certain route -- Use Controller action? - asp.net-mvc-4

I'm trying to serve image files from a specific url system, like so:
mysite/Images/Category/File_Name.extension
I've set up a route like so:
routes.MapRoute( "ImagesRoute", // Route name
"Images/{category}/{file}.jpg", // URL with parameters
new { controller = "Posts",
action = "ViewImage",
category = "", file = "" } // Parameter defaults
);
Which is supposed to map to my controller action:
public ActionResult ViewImage(string category, string file)
{
var dir = Server.MapPath("/Images");
var imgtitle = file.Replace("_", " ").Replace(".jpg", "");
var repos = new BlogImagesRepository();
var guid = repos.FetchImageByCategoryAndTitle(category, imgtitle);
var path = Path.Combine(dir, category, guid.ImageGuid.ToString());
return File(path, "image/jpeg");
}
If I remove the .jpg extension from the route and request a file title without the .jpg extension on the url (ie: Images/MyCategory/My_Image) it displays just fine.
However, adding the .jpg extension results in a 404 error--
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I assume it's looking for the file, instead of the controller action.
Adding the .jpg to the routes did not resolve this; I'm unsure what to do, and my google luck hasn't been very high with similar questions I saw on here.
How can I do this for .jpg, and similar image types? Do I have to set up an ignore for that particular path somehow? If so, how do I go about doing that? The application is just being ran through VS 2012 currently.

You're right in that requests for .jpg aren't being sent through to your Controller and handled by the static file handler of IIS. You don't really want an ignore, but you want to pass it through to the ASP.NET runtime. Most of the internet searches you'll find will tell you to add RunAllManagedModulesForAllRequests or something to that respect; however, this has a performance impact so the easiest way to do this is probably to add another TransferRequestHandler in your web config, like the MyJpgHandler example below:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="MyJpgHandler" path="Images/*/*.jpg" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
This should result in behaviour you're expecting (assuming you don't also have any .jpg files that are meant to be served as static content from the same url path)

Related

Filepond http uploading files IIS server setup problem 405

I'm trying to get a uploading script running, filepond, uploading files through webpage. On IIS10, on co-located server.
When uploading, using POST, I get the following error:
HTTP Error 405.0 - Method Not Allowed
The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.
in details:
Module DirectoryListingModule
Notification ExecuteRequestHandler
Handler StaticFile
Error Code 0x80070001
Requested URL https://www.example.com:443/upl/files/
Physical Path W:\www.example.com\www\upl\files\
Logon Method Anonymous
Logon User Anonymous
Request Tracing Directory C:\inetpub\logs\FailedReqLogFiles
port 443 is open.
The folder has the following web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Write, Execute, Script">
<remove name="StaticFile" />
<add name="StaticFile" path="*" verb="GET,HEAD,POST,DEBUG" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Write" />
</handlers>
</system.webServer>
</configuration>
The folder has the following attributes:
IIS > site > folder > configuration Editor > system.webServer/handlers
FROM SITE/upl/files Web.config > accesPolicy: Read, Write, Execute, Script
FROM SITE/upl Web.config > accesPolicy: Read, Execute, Script (no solution when adding "Write")
FROM ApplicationHost.config accesPolicy: "Read, Execute, Script"
Athentication: Anonymous Athentication status enabled, rest disabled
Handler Mappings > Static File
Path: *, State: enabled,
PathType: File or Folder,
Handler: StaticFileModule,DefaultDocumentModule,DirectoryListingModule,
Entry Type: Local
EDIT > Request Restrictions > Mapping : selected Invoke handler only if request is mapped to File or folder, Verbs: GET,HEAD,POST,DEBUG,
Access: Write ( I dont understant why there is no Read/Write option, only read / write / script / execute )
Properties > security >
even when giving full control on that folder to Everyone + IUSR + IIS_IUSRS + Users : still same error.
I did notice in Handler Mappings there is no *.js record.
In Handler Mappings changing the *.asp > edit > "file" to "file and folder" had no effect either.
Jic: I could not find Filepond using a temp folder that I forgot to give acces rights to.
Jic; these are my present FilePond server settings:
FilePond.setOptions({
server: {
url: 'https://www.example.com/upl/',
timeout: 3000,
process: {
url: 'files/',
method: 'POST',
headers: {
'x-customheader': 'Hello World',
},
withCredentials: false,
onload: (response) => response.key,
onerror: (response) => response.data,
ondata: (formData) => {
formData.append('Hello', 'World');
return formData;
},
},
revert: './revert',
restore: './restore/',
load: './load/',
fetch: './fetch/',
}
});
I looked at all the previous answers here and elsewhere for over a day now, but seem to miss a tiny vital thing. Any help is very much appreciated !!
Alex
------------ replying to Samwu:
Thank you for helping.
The above represents most of the solutions I looked at.
I followed the link, found this earlier and here are some findings:
the client makes a Hypertext Transfer Protocol (HTTP) request by using an HTTP method that doesn't comply with the HTTP specifications.
In the ApplicationHost.config file, Make sure that all the handlers use valid HTTP methods.
from my applicationHost.config:
<handlers accessPolicy="Read, Execute, Script">
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="File" />
<add name="StaticFile" path="*" verb="GET,POST" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Write" />
</handlers>
<sectionGroup name="webdav">
<section name="globalSettings" overrideModeDefault="Deny" />
<section name="authoring" overrideModeDefault="Deny" />
<section name="authoringRules" overrideModeDefault="Deny" />
</sectionGroup>
all the modules are stated in applicationHost.config modules
I did notice however something: in the www root there is a web.config that says:
<remove name="ASPClassic" />
<remove name="StaticFile" />
<add name="StaticFile" path="*" verb="GET,HEAD,POST,DEBUG" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Script" />
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Either" requireAccess="Script" />
</handlers>
in the upl / files / dir there is a webconfig saying:
<system.webServer>
<handlers accessPolicy="Read, Write, Execute, Script">
<remove name="StaticFile" />
<add name="StaticFile" path="*" verb="GET,HEAD,POST,DEBUG" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Write" />
</handlers>
</system.webServer>
notice the " requireAccess="Script" instead of Write
"Send the POST request to a page that's configured to be handled by a handler other than the StaticFile handler. For example, the ASPClassic handler. "
I assume that if my filepond js module is included in a .asp page that this is what I am all ready doing.
WebDav is not installed, it is still stated in the applicationHost.config. Removing that gives an error on restarting the site in IIS.
I hope that clearifies.

ApiDescriptions returns GET functions only

I'm trying to document my APIs. I've written in my controller the following code (VB.NET) :
Function Index() As ActionResult
Dim config = GlobalConfiguration.Configuration
Dim apiExplorer = config.Services.GetApiExplorer()
Dim apiDescs = apiExplorer.ApiDescriptions
Return View(apiExplorer)
End Function
The problem is when I debug my code and watch what is in the apiDescs, I can only see GET methods only - I can't see any DELETE, PUT or even POST methods. This is not how it should work.
Here is a sample from one of my APIs:
<HttpGet()>
Public Function GetX(x as integer) as String
'Code goes here
End Function
<HttpPost()>
Public sub PostX(x as integer)
'Code goes here
End Function
Only GetX is returned within ApiDescriptions without PostX. The same goes for all POST, PUT and DELETE methods in all APIs.
I've searched the web and I couldn't find an answer or a similar case to mine,so since I'm not sure what exactly was going on with my project I've created a new MVC WebAPI project,checked that everything is working,then compared webconfig files and it seems my project didn't have those handlers in <handlers> section:
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
After adding them my project worked fine and ApiDescriptions now lists all methods

How to make glimpse work with hot-towel mvc4?

I want to add glimpse diagnostic tool to my mvc4 hot-towel project.
I am following instruction http://nuget.org/packages/Glimpse.Mvc4/ and installing mvc4 nuget package of glimpse in my project.
It is getting installed properly and getting dependency and updating web.config as shown below.
<httpModules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" />
</httpModules>
<httpHandlers>
<add path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" />
</httpHandlers>
and
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
</modules>
and
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
<!-- If you are having issues with Glimpse, please include this. It will help us figure out whats going on.
<logging level="Trace" />-->
<!-- Want to use Glimpse on a remote server? Ignore the LocalPolicy by removing this comment.
<runtimePolicies>
<ignoredTypes>
<add type="Glimpse.AspNet.Policy.LocalPolicy, Glimpse.AspNet"/>
</ignoredTypes>
</runtimePolicies>-->
However, when i run project and type url such as http://mylocalurl.com/glimpse.axd . It is not finding axd file so i am unable to enable glimpse.
P.S. I have defined custom route for loading Index page for hot-towel template.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Load", action = "Index", id = UrlParameter.Optional }
);
}
The reason Glimpse.axd cannot be found is due to the order in which the routes are being configured.
If you install the RouteDebugger NuGet package you'll see that there is another route handling the Glimpse.axd request, namely a route installed by the Hot Towel template, which can be found inside the App_Start folder in the class HotTowelRouteConfig
using System.Web.Mvc;
[assembly: WebActivator.PreApplicationStartMethod(
typeof(throwaway.App_Start.HotTowelRouteConfig), "RegisterHotTowelPreStart", Order = 2)]
namespace throwaway.App_Start {
///<summary>
/// Inserts the HotTowel SPA sample view controller to the front of all MVC routes
/// so that the HotTowel SPA sample becomes the default page.
///</summary>
///<remarks>
/// This class is discovered and run during startup
/// http://blogs.msdn.com/b/davidebb/archive/2010/10/11/light-up-your-nupacks-with-startup-code-and-webactivator.aspx
///</remarks>
public static class HotTowelRouteConfig {
public static void RegisterHotTowelPreStart() {
// Preempt standard default MVC page routing to go to HotTowel Sample
System.Web.Routing.RouteTable.Routes.MapRoute(
name: "HotTowelMvc",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "HotTowel",
action = "Index",
id = UrlParameter.Optional
}
);
}
}
}
And since this route will be added before the execution of the RouteConfig.RegisterRoutes (due to the use of WebActivator), it will handle the request for Glimpse.axd, because that route has default values for every route parameter and therefore will match the Glimpse.axd request.
You can solve this by removing the HotTowelRouteConfig but then you'll have to go the example url explicitly http://mylocalurl.com/HotTowel/Index, or you remove the WebActivator part from the HotTowelRouteConfig
[assembly: WebActivator.PreApplicationStartMethod(
typeof(throwaway.App_Start.HotTowelRouteConfig), "RegisterHotTowelPreStart", Order = 2)]
and register the route explicitly in the RouteConfig.RegisterRoutes by calling HotTowelRouteConfig.RegisterHotTowelPreStart() after the call to routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); that way you'll still have the example by default and Glimpse.axd will be handled as expected.
Either way, both options involve removing or changing files managed by the HotTowel NuGet package, so maybe the example should be put into its own NuGet package (you don't want to bring the example into production for instance)
The newest source code checked in to the Hot Towel GitHub repository handles this slightly different.
In HotTowelRouteConfig the RegisterHotTowlPreStart function is changed to:
public static void RegisterHotTowelPreStart() {
// Ignore requests to .axd HttpHandlers
System.Web.Routing.RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Preempt standard default MVC page routing to go to HotTowel Sample
System.Web.Routing.RouteTable.Routes.MapRoute(
name: "HotTowelMvc",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "HotTowel",
action = "Index",
id = UrlParameter.Optional
}
);
This allows axd including Glimpse.axd to work, by excluding them from being handled by the sample.

Running ServiceStack side by side with MVC

I managed to run ServiceStack side by side with MVC4, but I still have a little problem and hope someone can help me with that.
When executing a debugging session through VS2012, everthying works perfect - the browser is opened and the first page is loaded well. But then when refreshing the page, and trying to get to http://localhost:62322/Content/site.css, the following error is displayed:
Handler for Request not found:
Request.ApplicationPath: /
Request.CurrentExecutionFilePath: /Content/site.css
Request.FilePath: /Content/site.css
Request.HttpMethod: GET
Request.MapPath('~'): D:\All\Projects\ExampleProject\trunk\ExampleProject\ExampleProject\
Request.Path: /Content/site.css
Request.PathInfo:
Request.ResolvedPathInfo: /Content/site.css
Request.PhysicalPath: D:\All\Projects\ExampleProject\trunk\ExampleProject\ExampleProject\Content\site.css
Request.PhysicalApplicationPath: D:\All\Projects\ExampleProject\trunk\ExampleProject\ExampleProject\
Request.QueryString:
Request.RawUrl: /Content/site.css
Request.Url.AbsoluteUri: http://localhost:62322/Content/site.css
Request.Url.AbsolutePath: /Content/site.css
Request.Url.Fragment:
Request.Url.Host: localhost
Request.Url.LocalPath: /Content/site.css
Request.Url.Port: 62322
Request.Url.Query:
Request.Url.Scheme: http
Request.Url.Segments: System.String[]
App.IsIntegratedPipeline: False
App.WebHostPhysicalPath: D:\All\Projects\ExampleProject\trunk\ExampleProject\ExampleProject
App.DefaultHandler: DefaultHttpHandler
App.DebugLastHandlerArgs: GET|/Content/site.css|D:\All\Projects\ExampleProject\trunk\ExampleProject\ExampleProject\Content\site.css
But if I delete the following line of code in AppHost.cs, everything works well, and the handler for site.css is always found:
SetConfig(new EndpointHostConfig { ServiceStackHandlerFactoryPath = "api", DefaultContentType = ContentType.Json });
My requirements for the project are wrapping with ServiceStack any call through the browser (all controllers) as well as calls to /api, which should be handled by a ServiceStack service.
I followed the instructions here:
https://github.com/ServiceStack/ServiceStack/wiki/Run-servicestack-side-by-side-with-another-web-framework
and my web.config looks like this:
<system.web>
<!--...-->
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
</httpHandlers>
<!--...-->
</system.web>
<location path="api">
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
</httpHandlers>
</system.web>
<!-- Required for IIS 7.0 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
</system.webServer>
</location>
Does anybody know why the handler for site.css sometimes found and sometimes not?
Furthermore, if I did a mistake with configuring ServiceStack to wrap my whole server, please point me to them.
From what you are trying to do I would recommend starting with a plain ASP.NET Web Application. Once your project is set, using NuGet you could do
Install-Package ServiceStack.Host.AspNet
or just follow the configuration here. Doing this runs ServiceStack at the root path /.
In your set up above you don't need this line...
SetConfig(new EndpointHostConfig { ServiceStackHandlerFactoryPath = "api", DefaultContentType = ContentType.Json });
Adding it is telling ServiceStack to only handle requests that contain the '/api' path which is not what you want.

REST methods not accessible when hosting wcf service in IIS

I have a WCF REST service that exposes a method in class GreetService:
[ServiceContract]
public class GreetService
{
[WebGet(UriTemplate = "greet/{name}")]
public String GreetName(string name)
{
return "Hello " + name;
}
}
Also, I registered a route in Global.asax:
RouteTable.Routes.Add(new ServiceRoute("GreetService", new WebServiceHostFactory(), typeof(GreetService)));
Now when i run this directly from visual studio, I am able to leverage the UriTemplate and invoke this method using a GET call to
http://localhost:5432/GreetService/greet/JohnDoe
However, after deploying this to IIS7 by creating a Greet.svc file for it, I am observing the following behavior:
I can call http://localhost:5432/Greet.svc and it says that a service has been created
I can point wcftestclient to http://localhost:5432/Greet.svc?wsdl to generate a test client which can call GreetName() directly
However, I can't call http://localhost:5432/Greet.svc/GreetService/greet/JohnDoe nor http://localhost:5432/Greet.svc/greet/JohnDoe although I expected to be able to since I specified an empty relative endpoint address in the corresponding web.config file prior to hosting it in IIS7.
Any ideas why the WebGetAttribute is not working in IIS? Or is there something else I am doing wrong?
EDIT:
This is the ServiceModel part of my web.config file which resides in the directory that IIS uses:
<system.serviceModel>
<!-- <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> -->
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
EDIT 2: For completeness' sake here is my full web.config file:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
<handlers>
<add name="UrlRoutingHandler"
preCondition="integratedMode"
verb="*" path="UrlRouting.axd"
type="System.Web.HttpForbiddenHandler,
System.Web, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
<system.serviceModel>
<!--<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>-->
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
If you've defined your route to be:
new ServiceRoute("GreetService", .....
then you should be able to call your service at
http://localhost:5432/YourVirtualDirectory/GreetService/greet/JohnDoe
and if your web app is deployed to your IIS root (not in a virtual directory), that would be:
http://localhost:5432/GreetService/greet/JohnDoe
When defining a ServiceRoute, that's done to get rid of having to specify the Greet.svc file, really - the ServiceRoute entry already contains all the information IIS needs to instantiate your service and call it - no need for having the *.svc file involved in your URL (the svc file basically contains the same info your ServiceRoute entry has).
Change the line in your global.asax.cs to read:
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(GreetService)));
and put the following in your web.config right under the root <configuration> node:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web.Routing, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=31BF3856AD364E35" />
</modules>
<handlers>
<add name="UrlRoutingHandler"
preCondition="integratedMode"
verb="*" path="UrlRouting.axd"
type="System.Web.HttpForbiddenHandler,
System.Web, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
(do make sure you're using the right .NET version) and see what that does for you.
NOTE: please post the web.config, at least the system.servicemodel part.
You normally use either the Route-based configuration or a .svc file, not both, but that's orthogonal to your problem. FWIW, you should be able to kill the .svc file once you get the service working and just use the route.
Since you're able to generate WSDL and call it, that sounds like you might not have webhttp as an endpoint behavior?
Make sure you have an endpoint behavior defined like this (can be a diff name of course)
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
and then make sure your service endpoint includes behaviorConfiguration="webHttpBehavior"
The problem is machine config missing the following section
<configSections>
<sectionGroup name="system.serviceModel" type="System.ServiceModel.Configuration.ServiceModelSectionGroup, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="standardEndpoints" type="System.ServiceModel.Configuration.StandardEndpointsSection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</sectionGroup>
</configSections>
Add it on top of web.config (after the opening tag of <configuration> ) should fix this problem.