I have looked a lot into ServiceStack question on Stackoverflow and really running out of options. Spent a lot of time and tried a lot of options but not being able to run my ServiceStack services in IIS.
I have a virtual directory under default website named api
and the physical location pointing that to is bin directory of ServiceStack assemblies.
Just for testing I have put an index.htm
in the bin folder. When I navigate to localhost/api
, I get the contents of index.htm from bin folder.
However as you see in below code, my client invocation of ServiceStack service via JSONServiceClient
results in 404 exception. I am not sure what am I missing.
Thanks much in advance.
using System.Configuration;
using ServiceStack.OrmLite;
using ServiceStack.OrmLite.SqlServer;
// logging
using ServiceStack.Logging;
// Service Interface project
public class xxxService : Service
{
public List<xxxResponse> Get(xxxQuery xxxQuery)
}
[Route("/xxxFeature/{xxxSerialNo}/{xxxVersion}")]
public class xxxQuery : IReturn<List<xxxResponse>>
{
public string xxxSerialNo { get; set; }
public string xxxVersion { get; set; }
public string xxxId { get; set; }
public string xxxName { get; set; }
}
public class xxxResponse
{
public int ID { get; set; }
public string Name { get; set; }
public string Version { get; set; }
public string Size { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<location path="api">
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
</httpHandlers>
<authorization>
<allow users="*" />
</authorization>
</system.web>
<!-- Required for IIS7 -->
<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>
<system.webServer>
<directoryBrowse enabled="false" />
</system.webServer>
</configuration>
Global.asax.cs
public class Global : System.Web.HttpApplication
{
public class xxxServiceAppHost : AppHostBase
{
public xxxServiceAppHost() : base("xxx Services", typeof(xxxService).Assembly)
{
ServiceStack.Logging.LogManager.LogFactory = new Log4NetFactory(true);
Log4NetUtils.ConfigureLog4Net(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["ServerDB"]].ConnectionString);
}
public override void Configure(Funq.Container container)
{
container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["ServerDB"]].ConnectionString, SqlServerDialect.Provider));
SetConfig(new EndpointHostConfig { ServiceStackHandlerFactoryPath = "api" });
}
}
Have also tried with routes.ignore
commented To avoid conflicts with ASP.NET MVC add ignore rule in Global.asax
. RegisterRoutes method e.g: routes.IgnoreRoute ("api/{*pathInfo}");
public void RegisterRoutes(RouteCollection routes)
{
routes.Ignore("api/{*pathInfo}");
}
protected void Application_Start(object sender, EventArgs e)
{
new xxxServiceAppHost().Init();
}
}
Client invocation. I have also tried with ..../api/api
because my vdir on IIS is api
.
try
{
xxxServiceClient = new JsonServiceClient("http://111.16.11.111/api");
List<xxxResponse> xxxResponses = xxxServiceClient.Get(new xxxQuery { xxxSerialNo = "22222", xxxVersion = "0.0" });
}
catch (WebServiceException excp)
{
throw excp;
}
It looks to me like there are a few things you can try with the web.config. You shoudln't need to have a virtual directory on the server. Depending on the version of IIS you are using you might still need both the httpHandlers and handlers config sections. I see your nesting the config settings for ServiceStack in the location path="api". That might make sense for your desired security requirements and why it is that you have an "api" virtual directory. You could try not using that location element.
Try the following: remove the location element and combine settings with your other config sections (system.web...etc), remove the httpHandlers section, keep the handlers section, and change the handlers config to have a path of "api*.
That will map the url to the services so the when you go to localhost:12345/api/metadata you should see your services. If you can't see the metadata page you know something isn't right.
independent of the web.config changes, there are issues with your service code. Your code seems to have a few things out of place. Your request object (xxxQuery) should be a simple POCO with your route attributes. The Get service needs to have that object as its parameter. The response should implement IHasResponseStatus if you are going to return that property.
<handlers>
<add path="api*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true"/>
</handlers>
// Service Interface project
public class xxxService : Service
{
public xxxResponse Get(xxxQuery xxxQuery)
{
//return object of type xxxResponse after doing some work to get data
return new xxxResponse();
}
}
[Route("/xxxFeature/{xxxSerialNo}/{xxxVersion}")]
public class xxxQuery
{
public string xxxSerialNo { get; set; }
public string xxxVersion { get; set; }
public string xxxId { get; set; }
public string xxxName { get; set; }
}
public class xxxResponse : IHasResponseStatus
{
public xxxResponse()
{
// new up properties in the constructor to prevent null reference issues in the client
ResponseStatus = new ResponseStatus();
}
public int ID { get; set; }
public string Name { get; set; }
public string Version { get; set; }
public string Size { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With