Using codec file extensions with OpenRasta returns 404 - openrasta

When using codec uri file extensions with OpenRasta, OR can't resolve the uri and returns a 404. Without the file extension all works ok.
The codecs are defined for the object resource and I'm using both XmlDataContract and JsonDataContract. Using neither the .xml or .json extension works, this is for both InMemoryHost (which we're using for testing) and ASP.Net (IIS7, integrated mode).
Codec configuration:
ResourceSpace.Has.ResourcesOfType<object>()
.WithoutUri
.AsXmlDataContract()
.And.AsJsonDataContract();
Is there anything else that needs to be done to make uri file extensions work?

You need to register the ContentTypeExtensionUriDecorator as a UriDecorator in OpenRasta in order to expose the .xml, .json functionallity.
The below example should allow you to make http requests to:
GET /home.json
GET /home.xml
public class RastaConfig : IConfigurationSource
{
public void Configure()
{
using(OpenRastaConfiguration.Manual)
{
ResourceSpace.Uses.UriDecorator<ContentTypeExtensionUriDecorator>();
ResourceSpace.Has.ResourceOfType<Home>()
.AtUri("/home")
.HandledBy<HomeHandler>()
.AsXmlDataContract()
.And.AsJsonDataContract();
}
}
}
This is because noramlly the client will add an HTTP Accept header to define the content types it supports and is interested in.
For more information you can read about Content Negotiation (often referred to as conneg) on the web.
OpenRasta will then select the return content type based on the client 's preference in the HTTP Accept header.
Hope this helps.

Related

How can I force the .NET ASMX WSDL generation to change a soap:address location from http to https?

Using VB.NET asmx project, which is hosted behind SSL offload, I need to change the generated WSDL to show https for the soap:address.
from: <soap:address location="http://example.com/example.asmx"/>
to: <soap:address location="https://example.com/example.asmx"/>
preferably outside of code so we can influence in the build process.
It depends what system are you using for generating the wsdl.
You shared that you are using VB.NET but it does not narrow down enough to answer your question a 100%. If you can show some code then we could help hopefully. Also as far as I remember, the location in the WSDL file is the same as the client is accessing it (the URL where it reaches). Meaning that as the offloading happens elsewhere the location could always be http.
Without further information I see three options for you:
Configure the TLS offloader to redirect the queries from http to httpS. (This is also a recommended setting from a security point of view.)
Where the offloading is happening use a solution to replace the content of the response. (This has the advantage of being specific to the environment.)
Use self singed certificate on the internal application as well, and therefore the address will be generated correctly. (This could be a bit tougher nut to crack, but has the benefit of not being dependent on other configuration and having to modify that configuration for every environment from development to live.)
In c# it could be done in code https://learn.microsoft.com/en-us/archive/blogs/kaevans/modify-a-web-services-wsdl-using-a-soapextensionreflector and is qite complicated. If you have a developer machine, then you need to use TLS as well... but here you go:
using System;
using System.Web.Services.Description;
namespace Msdn.Web.Services.Samples
{
public class HttpsReflector : SoapExtensionReflector
{
public override void ReflectMethod()
{
//no-op
}
public override void ReflectDescription()
{
ServiceDescription description = ReflectionContext.ServiceDescription;
foreach (Service service in description.Services)
{
foreach (Port port in service.Ports)
{
foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
{
SoapAddressBinding binding = extension as SoapAddressBinding;
if (null != binding)
{
binding.Location = binding.Location.Replace("https://", "https://");
}
}
}
}
}
}
}

Swashbuckle Swagger url from http to https .NET

My API is an HTTP API (not HTTPS) developped in ASP.NET.
Nevertheless, when deployed in the DMZ, there is something, somewhere on the network, not under my responsability, that only accept HTTPS and act as a reverse proxy to my HTTP API.
This leads to the swagger UI misbahaving.
The URL to access the swagger UI is "https://external_public_name/api/swagger/ui/index#/" but he one in the text field in the green ribbon is "http://external_public_name/api/swagger/docs/v1".
Therefore, the page is blank, with the error at the console
Mixed Content: The page at
'https://external_public_name/api/swagger/ui/index' was loaded over
HTTPS, but requested an insecure XMLHttpRequest endpoint
'http://external_public_name/api/swagger/docs/v1'. This request has
been blocked; the content must be served over HTTPS.
Replacing, manually the URL in the textbox with HTTPS is working fine.
Where should I change something to update that URL (maybe at runtime)?
P.S.: I already had to rewrite the SwaggerConfig.cs as SwaggerConfig.vb to be able to use it.
Imports System.IO
Imports System.Reflection
Imports System.Web.Http
Imports System.Web.Http.Description
Imports Swashbuckle.Application
Imports Swashbuckle.Swagger
<Assembly: PreApplicationStartMethod(GetType(SwaggerConfig), "Register")>
Public Class SwaggerConfig
Public Class KnownSubTypesDocumentFilter
Implements IDocumentFilter
Public Sub Apply(swaggerDoc As SwaggerDocument, schemaRegistry As SchemaRegistry, apiExplorer As IApiExplorer) Implements IDocumentFilter.Apply
schemaRegistry.GetOrRegister(GetType(BookController.BookList))
End Sub
End Class
Public Shared Sub Register()
Dim thisAssembly = GetType(SwaggerConfig).Assembly
GlobalConfiguration.Configuration.EnableSwagger(
Function(c)
c.Schemes({"https"})
c.SingleApiVersion("v1", "api")
c.DocumentFilter(Of KnownSubTypesDocumentFilter)()
Return c
End Function).EnableSwaggerUi(
Function(ui)
ui.DocumentTitle("Skippy's API")
ui.DocExpansion(DocExpansion.List)
ui.SupportedSubmitMethods()
Return ui
End Function)
End Sub
End Class

.Net MVC returning a File

I'm working a Controller that will generate/retrieve files. These will optionally set headers.
public IActionResult SampleFileReport()
{
I see the return type is IActionResult (a data contract). I see inside the function I can still set
response.ContentType
Is there a preferred pattern for how to set ContentType in a controller?
I'm thinking it should be part of the DataContract and setting response.contentype is an anti-pattern, however I see examples such as this that utilize it. Returning a file to View/Download in ASP.NET MVC
All you need to do is return File:
public IActionResult SampleFileReport()
{
// do stuff
return File(bytes, mimetype, filename);
}
File also has overloads that accept Stream and string (path and filename to a file on the filesystem) in addition to byte[]. The mimetype is your content type, e.g. application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (Excel), etc. The final filename param is optional. If it's provided, a Content-Disposition: attachment header is sent with the response, which prompts the browser to pop a download dialog. Otherwise, the default Content-Disposition: inline is used, and the browser will try to load the returned file directly the browser tab/window, assuming the mime-type is supported for native rendering the browser. If not, then you'll get a download dialog, regardless.
If we are talking about MVC (not .NET Core) then you can change IActionResult to FileContentResult
public FileContentResult SampleFileReport()
{
byte[] fileBytes = GetFileBytes();
return File(fileBytes, MediaTypeNames.Application.Octet, "fileName");
}
Just checked this class still exists. FileContentResult .NET Core

How to generate dynamic response from the stubs without re-generating it again?

I know Groovy DSL is able to generate a random value.
I have used stub runner server so that I can hit the stubs from the server and get response. however when I refresh the browser I get the same response again. The Groovy DSL is just generating a static stub, and is always returning the same response as I requested.
How can I get a random response without re-generate the stubs in this case?
Also a similar question was asked by someone a year ago, it was written in the answer that it is not possible. Is it still not possible or there is a way now to do it?
You would have to create your own WireMock extension. Check this section of the docs: https://docs.spring.io/spring-cloud-contract/docs/current/reference/html/advanced.html#customization-wiremock
95.5.6 Registering Your Own WireMock Extension WireMock lets you register custom extensions. By default, Spring Cloud Contract
registers the transformer, which lets you reference a request from a
response. If you want to provide your own extensions, you can register
an implementation of the
org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions
interface. Since we use the spring.factories extension approach, you
can create an entry in META-INF/spring.factories file similar to the
following:
org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions=\
org.springframework.cloud.contract.stubrunner.provider.wiremock.TestWireMockExtensions
org.springframework.cloud.contract.spec.ContractConverter=\
org.springframework.cloud.contract.stubrunner.TestCustomYamlContractConverter
The following is an example of a custom extension:
TestWireMockExtensions.groovy.
package org.springframework.cloud.contracthttps://docs.spring.io/spring-cloud-contract/docs/current/reference/html/advanced.html#customization-wiremock.verifier.dsl.wiremock
import com.github.tomakehurst.wiremock.extension.Extension
/** * Extension that registers the default transformer and the custom one */ class TestWireMockExtensions implements WireMockExtensions { #Override List<Extension> extensions() { return [
new DefaultResponseTransformer(),
new CustomExtension() ] } }
class CustomExtension implements Extension {
#Override String getName() { return "foo-transformer" } }
You would have to create an extension that modifies the response and generates a piece of it. That extension needs to be available both on the consumer and the producer sides.

How can DELETE requests be made with a Dart HttpClient?

If you're using a Dart HttpClient (which provides an HttpClientRequest) to make requests from a server to another server, as far as I can tell the only HTTP methods available are GET and POST (corresponding, respectively, to the post/postUrl and get/getUrl functions). Is there also a way to make PUT and DELETE requests?
You should be able to do with this with the open method which allows you to use any HTTP verb:
client.open('delete', 'http://example.com', '8080', '/test');
If you look at the HttpClient source you'll see that the get and post methods are just aliases for open anyway:
Future<HttpClientRequest> post(String host,
int port,
String path) {
return open("post", host, port, path);
}

Resources