I am trying to hook up Swagger to a VB.Net REST API project. No matter what I try the app continues to return a 404 response when hitting the swagger/ui/index URL. Initially, on start-up I enter the following URL: http://localhost/ApiNameHere/Swagger.
IIS attempts to access (redirects to) http://localhost/swagger/ui/index. This returns a 404 response.
Swashbuckle was used to install Swagger
Locally, the app runs in IIS.
I have seen recommendations to delete the .vs folder. I have tried that, to no avail.
Here is the SwaggerConfig.vb file:
Public Class SwaggerConfig
Public Shared Sub Register(config As HttpConfiguration)
Dim thisAssembly = GetType(SwaggerConfig).Assembly
config.EnableSwagger(
Sub(c)
c.SingleApiVersion("v1", "ApiNameHere")
End Sub
).EnableSwaggerUi()
End Sub
End Class
Here is the relevant Startup.vb code :
Dim config = New HttpConfiguration()
config.MapHttpAttributeRoutes()
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", New With {RouteParameter.Optional})
SwaggerConfig.Register(config)
app.UseWebApi(config)
Any thoughts?
Related
I have an app which will download publicly available data as a string from a website.
The below code on a WinForm app on Windows 10 works perfectly, but it doesn't work at all on Windows Server 2019.
I have tried enabling the "Allow App Through Firewall" option & have also tried allowing the program in outbound rules in the firewall, but nothing is working.
What is the issue?
Private Async Function Run_WebRequest(URL As String) As Task(Of String)
Try
Dim client As WebClient = New WebClient()
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
client.Headers.Add("scheme", "https")
client.Headers.Add("accept-language", "en-US, en;q=0.9, ml;q=0.8")
Dim Response = client.DownloadString(URL)
Return Response
Catch ex As Exception
Return ex.ToString
End Try
End Function
I missed to add that this is a Virtual Private Server OS Windows Server 2019 from Contabo hosting services
Please see below screenshot of the app which is a standalone exe file with three buttons having different Webclients for testing, none of them works on
I have an action that returns a "mp3" file using FileResult, but I want to change the route to have the extension in the end of the route :
[HttpGet("{fileid}.mp3")]
public IActionResult GetFile(string fileid){
}
It works locally and returns the file. But when deployed to IIS, it throw 404 error.
Is there any configuration that I had to do ?
I am trying to setup an "external" web api that will be able to receive in large http posts (+1GB) and forward the stream to another "internal" web api that writes the request contents to a file. I have model my implementation based on examples of using a custom WebHostBufferPolicySelector and using the UseBufferedInputStream method in the controller method. It works as expected when using IIS Express, no significate increase in memory footprint, but as soon as my code is deployed to IIS, the memory footprint is substantial and results in OOM.
I have put tracing statements in my controller methods and in my WebHostBufferPolicySelector.UseBufferedInputStream, and have verified that UseBufferedInputStream always is returning false and that my controller methods are getting hit. The only difference that I noticed is that when I debug, the time stamps between UseBufferedInputStream and my controller method are very close. Where hosted on IIS, the time stamps are very far apart, suggesting that something in between when UseBufferedInputStream is called and my controller method is called is buffering up the request entirely.
I am looking for some tips on to find out what that is causing the request to get buffered and how for it not to buffer and using streaming all the way.
Client is coming at the external web api with a content type of application/octet-stream with Transfer Encoding of Chucked.
Used to build out implementation
https://forums.asp.net/t/2018289.aspx?Web+API2+WebHostBufferPolicySelector+UseBufferedInputStream+override
https://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/
Proxy Web Api Controller Method
<HttpPost, Route("postLargeFile")>
Protected Overridable Async Function PostLargeFile() As Threading.Tasks.Task(Of IHttpActionResult)
Configuration.Services.GetTraceWriter.Info(Request, $"{Me.GetType.Namespace}.{NameOf(MyProxyController)}", "Started {0}", NameOf(MyProxyController.PostLargeFile))
Dim internalHttpClient As HttpClient
Dim fowardingContent As StreamContent = Nothing
Dim fowardingMessage As HttpRequestMessage = Nothing
Dim fowardingResponse As HttpResponseMessage = Nothing
Dim externalResponse As HttpResponseMessage = Nothing
Try
internalHttpClient = New HttpClient()
internalHttpClient.BaseAddress = "https://myinternalService.com"
fowardingMessage = New HttpRequestMessage(HttpMethod.Post, "https://myinternalService.com/saveLargeFile")
fowardingContent = New StreamContent(HttpContext.Current.Request.GetBufferlessInputStream(True))
CopyContentHeaders(Request.Content, fowardingContent)
fowardingMessage.Headers.TransferEncodingChunked = True
fowardingMessage.Content = fowardingContent
fowardingResponse = Await internalHttpClient.SendAsync(fowardingMessage, HttpCompletionOption.ResponseHeadersRead)
externalResponse = New HttpResponseMessage(fowardingResponse.StatusCode)
externalResponse.Content = New StreamContent(Await fowardingResponse.Content.ReadAsStreamAsync)
CopyContentHeaders(fowardingResponse.Content, externalResponse.Content)
Return New Results.ResponseMessageResult(externalResponse)
Catch ex As Exception
Return InternalServerError(ex)
Finally
Configuration.Services.GetTraceWriter.Info(Request, $"{Me.GetType.Namespace}.{NameOf(MyProxyController)}", "Finished {0}", NameOf(MyProxyController.PostLargeFile))
End Try
End Function
Internal Web Api Controller Method
<HttpPost, Route("saveLargeFile")>
Protected Overridable Async Function SaveLargeFile() As Threading.Tasks.Task(Of IHttpActionResult)
Configuration.Services.GetTraceWriter.Info(Request, $"{Me.GetType.Namespace}.{NameOf(MyInternalController)}", "Started {0}", NameOf(MyInternalController.PostLargeFile))
Dim bufferlessStream As IO.Stream
Dim fowardingContent As StreamContent = Nothing
Try
bufferlessStream = HttpContext.Current.Request.GetBufferlessInputStream()
Using fileStream As IO.FileStream = IO.File.Create("MyFile.txt")
bufferlessStream.CopyTo(fileStream)
fileStream.Flush()
End Using
Return New Results.StatusCodeResult(Net.HttpStatusCode.Created, Me)
Catch ex As Exception
Return InternalServerError(ex)
Finally
Configuration.Services.GetTraceWriter.Info(Request, $"{Me.GetType.Namespace}.{NameOf(MyInternalController)}", "Finished {0}", NameOf(MyInternalController.PostLargeFile))
End Try
End Function
Policy Selector Configuration
Public Class MyBufferPolicySelector
Inherits Http.WebHost.WebHostBufferPolicySelector
Public Property Tracer As ITraceWriter
Public Overrides Function UseBufferedInputStream(hostContext As Object) As Boolean
UseBufferedInputStream = False
Tracer?.Info(Nothing, $"{Me.GetType.Namespace}.{NameOf(MyBufferPolicySelector)}", "{0} UseBufferedInputStream={1}", HttpContext.Current?.Request?.Url?.AbsoluteUri, UseBufferedInputStream)
Return UseBufferedInputStream
End Function
End Class
WebApiConfig for both Internal and External Web APIs
Public Module WebApiConfig
Public Sub Register(ByVal config As HttpConfiguration)
Dim tracer As SystemDiagnosticsTraceWriter
' Web API configuration and services
' Web API routes
config.MapHttpAttributeRoutes()
tracer = config.EnableSystemDiagnosticsTracing
tracer.IsVerbose = True
tracer.MinimumLevel = Tracing.TraceLevel.Debug
GlobalConfiguration.Configuration.Services.Replace(GetType(IHostBufferPolicySelector), New MyBufferPolicySelector() With {.Tracer = tracer})
End Sub
End Module
I was able to figure out what was causing the the buffering in IIS. The below link lead me to the uploadReadAheadSize setting in IIS. This was maxed out. So this would cause IIS to fully read in/buffer in the request before passing it into the module where the web api pipeline exists (web api controllers). After setting it to the default, I saw my large file posts not get buffered, the app pool memory footprint remained low, no more out of memory exceptions, and a large performance boost. Great!
But now I have the same issue as described in the below link. When SSL is required, set in IIS, which it is required in our non development environments, the uploadReadAheadSize needs to be increased so the ssl can work in the ssl module I guess. It might have to do with some SSL renegotiation.
Can anybody describe a way to prevent the buffering in SSL to keep the memory footprint low and prevent out of memory exceptions for large http posts?
Large file upload when using ssl and client certificates (uploadReadAheadSize) but dont want all data to be readahead
I have a MVC 4 app in which i am wanting to use the web api to get my data. EDIT- this is a Single Page Application that started out with the Hot Towel Template. The problem is that I get the 404 resource not found when i try to call the controller from JSON. Here is my Controller-
Public Class CAApprovalController
Inherits ApiController
Public Function GetValues() As IEnumerable(Of String)
Return New String() {"value1", "value2"}
End Function
End Class
Here is my JSON call-
function getallCertificates() {
$.getJSON('api/CAApproval', function (data) {
allCertificates([]);
var temp = allCertificates();
data.forEach(function (p) {
var certificate = new Certificate(p.ClientID, p.RequestDate, p.UserName, p.StatusDescription, p.StatusCode, p.StatusDesc, p.CEOUserName);
temp.push(certificate);
});
allCertificates.valueHasMutated();
return allCertificates();
});
}
Here is the webapiconfig-
Public Class WebApiConfig
Public Shared Sub Register(ByVal config As HttpConfiguration)
config.Routes.MapHttpRoute( _
name:="DefaultApi", _
routeTemplate:="api/{controller}/{id}", _
defaults:=New With {.id = RouteParameter.Optional} _
)
'To disable tracing in your application, please comment out or remove the following line of code
'For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing()
'Use camel case for JSON data.
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = New CamelCasePropertyNamesContractResolver()
End Sub
End Class
I am new to MVC and especially web api, and am thinking it is a newbie issue. Just not sure what the problem is. Is there a configuration or something i am missing? The project was created as a MVC 4 / web api application.
Found the problem at last. Turns out that Breezejs was the problem. My app is a single page application, and Breeze was one of the components of my SPA app (Breeze was installed as part of the Hot Towel template i was using). Not sure why, but when i uninstalled Breeze, the controllers i added to the project became visible. Something in the breeze scripts hi-jack the api routing.
Are you hosting your web api in IIS or running it from Visual Studio. If IIS, /LucasNetApp/api/caaproval. If Visual Studio, /api/caaproval.
You realize that "api/..." means "from the current relative location" right?
You probably want "/api/..." in your ajax call.
EDIT:
It's better to use a Url Helper.
$.getJSON('#Url.HttpRouteUrl("DefaultApi", new { controller = "CAApproval" })', function (data) {
I'm trying to call the AddAttachment of the Lists.asmx SharePoint web service the below code works fine if I'm calling the web service over HTTP.
Dim img(MyFile.PostedFile.ContentLength - 1) As Byte
MyFile.PostedFile.InputStream.Read(img, 0, img.Length)
'Dim fStream As FileStream = File.OpenRead(FullFileName)
Dim fileName As String = MyFile.PostedFile.FileName.Substring(3)
Dim listService As New wsList.Lists()
Dim credentials As New System.Net.NetworkCredential(UserName, Password, Domain)
If Not SiteUrl.EndsWith("/") Then
SiteUrl += "/"
End If
SiteUrl += "_vti_bin/Lists.asmx"
'SiteUrl = SiteUrl.ToLower.Replace("http:", "https:")
listService.Url = SiteUrl
listService.Credentials = credentials
Dim addAttach As String = listService.AddAttachment(ListName, ItemId, fileName, img)
ReturnValue = True
However if I uncomment out this line
'SiteUrl = SiteUrl.ToLower.Replace("http:", "https:")
I will get the following error: The request failed with HTTP status 401: Unauthorized
Now if I leave the above line commented out AND then also comment out this line
listService.Credentials = credentials
I will get the same 401 error (expected) so it appears the credentials are being accepted correctly over HTTP but not HTTPS. Can one help explain this to me and have any thoughts on how to fix the issue?
Thanks in advance!
This morning I was working with one of our system guys. He checked some IIS logs and could see errors trying to access the web service over HTTPS. He went into Central Admin and added some Alternate Access Mappings to include the HTTPS urls. Then everything worked!