Swagger with Service Stack not working - c#

I am trying to implement Swagger with Service Stack. I've installed service stack with swagger using nuget. Current DLL versions are reported as 3.9.56.0 mostly.
I am trying to follow the example provided at...
https://github.com/ServiceStack/ServiceStack.UseCases/tree/master/SwaggerHelloWorld
and the instrucstion appear fairly fool-proof...
Plugins.Add(new ServiceStack.Api.Swagger.SwaggerFeature());
goes into the 'Configure' method after I've installed via nuget (as the documentation instructs), then I've added [ApiMember] and [Api] tags, along with changes to the [Route] tags to add Summary and Notes
but when I visit ~/swagger-ui/index.html i get the error
Please specify the protocol for ../api
My api sits at ~/api, and I have a single method at the moment (Hello World) sitting at ~api/Hello/{name} which returns JSON and works ok.
if I visit ~apii get the message Handler for Request not found: with a stack trace type output.
What am I doing wrong? The instructions to enable swagger appear really straight forward, and detailed instructions appear to be lacking, probably because it should 'just work', please help!
Update to address Esker...
Stack trace # myhost:54011/api
Handler for Request not found:
Request.ApplicationPath: /
Request.CurrentExecutionFilePath: /api
Request.FilePath: /api
Request.HttpMethod: GET
Request.MapPath('~'): D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\
Request.Path: /api
Request.PathInfo:
Request.ResolvedPathInfo: /api
Request.PhysicalPath: D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\api
Request.PhysicalApplicationPath: D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\
Request.QueryString:
Request.RawUrl: /api
Request.Url.AbsoluteUri: http://localhost:54011/api
Request.Url.AbsolutePath: /api
Request.Url.Fragment:
Request.Url.Host: localhost
Request.Url.LocalPath: /api
Request.Url.Port: 54011
Request.Url.Query:
Request.Url.Scheme: http
Request.Url.Segments: System.String[]
App.IsIntegratedPipeline: True
App.WebHostPhysicalPath: D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger
App.WebHostRootFileNames: [global.asax,global.asax.cs,helloservice.cs,jquery-1.10.2.js,packages.config,servicestackswagger.csproj,servicestackswagger.csproj.user,web.config,web.debug.config,web.release.config,app_data,app_start,bin,controllers,dto,models,obj,properties,swagger-ui,views]
App.DefaultHandler: metadata
App.DebugLastHandlerArgs: GET|/api|D:\Starteam\Private\user\web\ServiceStackSwagger\ServiceStackSwagger\api
Also, "Please specify protocol' is a swagger error, displayed onscreen in html underneath the aforementioned 'textbox to change discovery url'
and the DLL versions are 'mostly' the same because ServiceStack.Redis is version 3.9.57.0, but I'm not using that, so 'mostly'
Update... My Solution
I needed this in my web.config file inside of the <configuration> tag, I had previously not included the <location path="api"> bit.
<!-- ServiceStack: CustomPath /api -->
<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>
also... I had set up my 'routes' as such...
//INCORRECT
[Route("/api/Hello/{name}", Summary = #"N031'5 ServiceStackSwagger thingy", Notes = "Some more info in here cause these are notes")]
public class Hello : IReturn<HelloResponse>
but that messed with swagger's functionality, it needed to be...
//CORRECT
[Route("/Hello/{name}"...
with the 'api' bit REMOVED, and now everything is working.

You need to tell Swagger about the specific URL of the ServiceStack Swagger endpoint, rather than the base URL of your services. This endpoint is located at /resources under your base URL. So, instead of ../api for the discoveryUrl, use ../api/resources, like so, in your index.html file:
window.swaggerUi = new SwaggerUi({
discoveryUrl: '../api/resources',
...

Related

ASP.Net 403 error when adding new razor .cshtml file type

I am working in an environment in which are views are requested via a JQuery viewLoader GET request. I'm trying to port all .html to Razor (.cshtml) and I consistently get 403 errors from the client side when I change the extension on the src property to .cshtml. Note I am doing this because if I keep the request as .html I get a 404 (I thought the cshtml would serve itself as html?) :
var cartContainerScript = <script id='CartContainerTemplate' type='text/html' src='./Views/Home/Carts/ED.cshtml' ></script>
$("body").append(cartContainerScript);
cartTemplate = $("script[id=" + 'CartContainerTemplate' + "]");
cartContainer.viewloader({
logLevel: "debug",
scripts: cartTemplate,
success: function (resolution) {
//Do good stuff
},
error: function (failedResolution) {
// 403 occurs # jquery-1.8.3.min.js:2 -> GET http://application.company.com/Views/Home/Carts/ED.cshtml 403 (Forbidden)
}
});
I tried adding a *.cshtml entry in the last line of the below HTTP routing in my Views/Web.config file with no luck:
<httpHandlers>
<add path="*.aspx;*.ascx" verb="*" type="System.Web.HttpNotFoundHandler"/>
<remove path="*.view.html" verb="*" />
<remove path="Carts\*.html" verb="*" />
<remove path="Carts\*.cshtml" verb="*" />
</httpHandlers>
Is there anyway to serve up the Razor files as html after compilation? Perhaps I am missing something in my web.config?
Thanks for looking!
In my case, I have to change <modules> to <modules runAllManagedModulesForAllRequests="true">
<system.webServer>
...
<modules> => <modules runAllManagedModulesForAllRequests="true">
...
</system.webServer>
This Web.config is at the root directory, not the one in Views directory.
But still, without IIS settings and Web.Config details, it's hard to tell what would cause this issue.

ASP.NET Server error in '/' application - ashx handler

I'm making a local CMS where I can create/edit/delete Posts, Tags, Authors and Roles, using *.ashx handlers. The Posts and Tags had been working fine, until I added functionality for authors and roles. Since adding those, whenever I tried to create/edit/delete a Post or Tag, I received the "Server error in '/' application: Resource cannot be found" error with, for example, Requested URL: /admin/post.ashx.
I found that it was most likely due to a copy/paste typo I made in web.config for removing and adding handlers, where I removed the Post and Tag handlers twice:
<system.webServer>
<handlers>
<remove name="PostHandler"/>
<add name="PostHandler" type="PostHandler" verb ="POST" path="/admin/post.ashx"/>
<remove name="TagHandler"/>
<add name="TagHandler" type="TagHandler" verb ="POST" path="/admin/tag.ashx"/>
<remove name="PostHandler"/>
<add name="AccountHandler" type="AccountHandler" verb ="POST" path="/admin/account.ashx"/>
<remove name="TagHandler"/>
<add name="RoleHandler" type="RoleHandler" verb ="POST" path="/admin/role.ashx"/>
</handlers>
</system.webServer>
The handler code now looks like this:
<system.webServer>
<handlers>
<remove name="PostHandler"/>
<add name="PostHandler" type="PostHandler" verb ="POST" path="/admin/post.ashx"/>
<remove name="TagHandler"/>
<add name="TagHandler" type="TagHandler" verb ="POST" path="/admin/tag.ashx"/>
<remove name="AccountHandler"/>
<add name="AccountHandler" type="AccountHandler" verb ="POST" path="/admin/account.ashx"/>
<remove name="RoleHandler"/>
<add name="RoleHandler" type="RoleHandler" verb ="POST" path="/admin/role.ashx"/>
</handlers>
</system.webServer>
However, having corrected the typos, I'm still receiving the same error for posts and tags only. I've tried rebuilding the solution, rebuilding website, reloading visual studio and clearing cache/browsing history, etc. in my browser, but I'm still having a problem creating/editing/deleting Posts and Tags. Roles and Accounts are fine.
I'm completely stumped - any ideas on what I need to do to rectify this?
You can try to clean the solution before rebuilding it.
If that doesn't work too, try changing the key names like MyTagHandler for TagHandler.

Glimpse works locally, not on remote server

After following all the guides, SO pages and troubleshooting pages I can find I'm finally out of ideas.
I've got Glimpse working fine on my local dev server, but when I deploy my ASP.net (MVC5) app to my remote server it doesn't work - at all. /glimpse.axd gives a 404 with both LocalPolicy and ControlCookiePolicy set to ignore, and with a custom security policy that returns On in all cases. My understanding is that with ControlCookiePolicy disabled, I shouldn't need to go to /glimpse.axd to enable it - but I'm not seeing the glimpse icon on the remote server either.
Even if I go to the remote server and browse localhost to /glimpse.axd I still get a 404.
My web.config looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
</configSections>
<system.web>
<compilation debug="false" />
<httpRuntime targetFramework="4.5.1" relaxedUrlToFileSystemMapping="true" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthentication" />
</modules>
<urlCompression doDynamicCompression="true" dynamicCompressionBeforeCache="false" />
</system.webServer>
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
<logging level="Trace" />
<runtimePolicies>
<ignoredTypes>
<add type="Glimpse.AspNet.Policy.LocalPolicy, Glimpse.AspNet" />
<add type="Glimpse.Core.Policy.ControlCookiePolicy, Glimpse.Core" />
</ignoredTypes>
</runtimePolicies>
</glimpse>
</configuration>
This is the version off the remote server (after transform). I've trimmed it a little to remove sections like appSettings.
My GlimpseSecurityPolicy.cs looks like this:
// Uncomment this class to provide custom runtime policy for Glimpse
using Glimpse.AspNet.Extensions;
using Glimpse.Core.Extensibility;
namespace RationalVote
{
public class GlimpseSecurityPolicy:IRuntimePolicy
{
public RuntimePolicy Execute(IRuntimePolicyContext policyContext)
{
return RuntimePolicy.On;
}
public RuntimeEvent ExecuteOn
{
// The RuntimeEvent.ExecuteResource is only needed in case you create a security policy
// Have a look at http://blog.getglimpse.com/2013/12/09/protect-glimpse-axd-with-your-custom-runtime-policy/ for more details
get { return RuntimeEvent.EndRequest | RuntimeEvent.ExecuteResource; }
}
}
}
The real one does an actual check, but I get the same issue with the policy above.
I cannot seem to find any trace output anywhere on the remote server, it is logging fine on my local machine.
I am deploying using the Visual Studio publish to web feature, and I've verified that the Glimpse.Core.dll is in the bin folder.
I can't see anything in the event log that is relevant.
I've also added <add namespace="Glimpse.Mvc.Html" /> to the namespaces block of the web.config in the views folder.
I tried putting #Html.GlimpseClient() in the _Layout.cshtml file just above </body> but this renders nothing.
Anybody got any ideas?
If the glimpse.axd is returning a 404 then this means the Glimpse resource handler is not registered.
If the web.config content you show above is not trimmed to much, then it is normal that Glimpse won't do much as the Glimpse HttpModule and the Glimpse HttpHandler are not registered in the system.web and/or the system.webserver sections like this
<system.web>
<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>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode"/>
</modules>
<handlers>
<add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
</handlers>
</system.webServer>
Maybe your transform removed to much from the local web.config?

404 after upgrading ServiceStack from 3.9.8 to 3.9.70 (new API)

We've been using a legacy version (3.9.8) of ServiceStack for a while now and I decided to try an upgrade to the latest version (3.9.70) and while it was a clean, no hassle package upgrade - everything compiles and runs - every service URL now returns a "Handler for Request not found" 404 result.
An example of a URL that used to work:
http://somewebserver.com/services/servicestack/jsv/syncreply/getuser
We use the old API (IService<T>) and make no use of REST routes or anything of the sort.
The ServiceStack application runs inside an ASP.NET MVC 3 web application, which lives on the URL http://somewebserver.com/management/controller/action. It doesn't seem like it's interfering as it's been configured to ignore the ServiceStack route:
routes.IgnoreRoute("servicestack/{*pathInfo}");
The ServiceStack code is definitely running as going to http://somewebserver.com/services/servicestack redirects me to the metadata page, which works.
I've tried following these steps:
https://github.com/ServiceStack/ServiceStack/wiki/Run-servicestack-side-by-side-with-another-web-framework
But it doesn't seem to make a difference.
What I changed in the config to try and make this work:
1) Removed this old line in system.webServer/handlers
<add path="servicestack" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
2) Added this location section:
<location path="servicestack">
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
</httpHandlers>
</system.web>
<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>
3) Added this in the app host setup:
this.Config.ServiceStackHandlerFactoryPath = "servicestack";
Calling the URL fails for both POST and GET, which used to both work.
This is all running under IIS 8.
I'd love to know what's going on here, so we can finally upgrade and live in 2013 :)
Apparently, the fix was in how we enabled the ServiceStack features. I didn't make the change myself, but these are the fixes:
Removed from AppHost:
this.Config.EnableFeatures = Feature.Metadata | Feature.Jsv | Feature.Json;
this.Config.ServiceStackHandlerFactoryPath = "servicestack";
Replaced by:
Feature disableFeatures = Feature.Soap;
SetConfig(new EndpointHostConfig
{
ServiceStackHandlerFactoryPath = "servicestack",
EnableFeatures = Feature.All.Remove(disableFeatures),
DebugMode = false,
WriteErrorsToResponse = false,
DefaultContentType = ContentType.Jsv,
AllowJsonpRequests = false
});

Canceling request validation using HttpHandler on IIS 7

I have an application that has to deal with getting "special" characters in its URL (like &, +, %, etc). When I'm sending a request to the application using these characters (of course I'm sending them escaped) I'm getting "Bad Request" response code with the message "ASP.NET detected invalid characters in the URL". Tracing the request shown me that the error was thrown from the "Authentication Module".
I've searched a bit and found that every page has a ValidateRequest and changing its value to false solves the problem. Unfortunately I'm using Httphandler. Does anyone know how to stop the request validation using http handler?
I ran into the same problem (creating an IHttpHandler that needed to receive requests with special characters in the URL). I had to do two things to fix it:
Create the following DWORD registration entry with a value of 1: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\VerificationCompatibility
In the web.config, set the allowDoubleEscaping attribute of the requestFiltering element to true.
I had the same problem and got it working by setting validateRequest="false" as well as requestValidationMode="2.0", like below. No registry edits.
<system.web>
<httpRuntime requestValidationMode="2.0" />
...
<pages ... validateRequest="false" />
</system.web>
Wholesale changes at the application or machine level were not acceptable to me. I only had one parameter that a client was sending incorrectly that I needed to scrub.
I found that when a request is made with html or other potentially dangerous items in the query string, you can scrub the string by using the context.Request.RawUrl and, once the query string is scrubbed, use context.RewritePath(scrubbedUrl).
First thing in the handler, get the context.Request.RawUrl
Scrub the bad request RawUrl for bad input
context.RewritePath(srubbedUrl)
Profit
It seems like request validation only cares about accessing context.Request.Params[], so if you scrub and rewrite path (to the same path) before the Params collection is accessed, you're golden.
Below solution worked for me-
Create the following DWORD registration entry with a value of 1: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\VerificationCompatibility
In the web.config, set the allowDoubleEscaping attribute of the requestFiltering element to true.
You can remove all the modules with
<httpModules>
<clear />
</httpModule>
to make the request get to your handler. Or maybe you can remove the specific modules that are stopping your request.
This is the list of modules loaded by default in ASP.NET 2.0 from here
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" />
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" />
<add name="Profile" type="System.Web.Profile.ProfileModule" />
</httpModules>
How about this?
<system.web>
<pages validateRequest="false">
</pages>
</system.web>
Since .NET Framework 4.5, you can use the Unvalidated property on HttpRequest or HttpRequestBase to access form, query string and URL data in a way that will not trigger request validation. If you avoid accessing these values in any other way (including in helper methods or other HTTP modules running in the same request), you will not require anything else to avoid request validation.
You can set validateRequest to false in the pages section of the web.config. Maybe that works for HttpHandlers as well?

Categories

Resources