Swashbuckle Swagger asking for api-version? - c#

We have implemented api versioning as mentioned here https://referbruv.com/blog/integrating-aspnet-core-api-versions-with-swagger-ui/
But why are we getting this api-version fields when it should know that it is version 2?
I have decorated the endpoint with the following yet it still displays this api-version field?
[HttpGet("summary/all")]
[MapToApiVersion("1.0")]
I have also done the same for the v2 endpoint but change to 2.0

Adding the ApiVersionReader seemed to correct this:
services.AddApiVersioning(setup =>
{
setup.AssumeDefaultVersionWhenUnspecified = true;
setup.DefaultApiVersion = new ApiVersion(1, 0);
setup.ReportApiVersions = true;
setup.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
new HeaderApiVersionReader("x-api-version"),
new MediaTypeApiVersionReader("x-api-version"));
});
A full example of what works for me can be found as the answer in this question Replacing app.UseMvc() with app.UserRouting() gives us error `The request matched multiple endpoints`

Related

C# Bound library method doesn't accept implementation parameter

Trying to implement the new SnapChat Creative Kit in Xamarin.iOS, I bound the SDK framework using Objective Sharpie. While following the official documentation (which only has implementation steps for swift and obj-c) for other SDKs wan not a problem - I successfully implemented Login Kit - I came to a stumble with this code while trying to send the content to SnapChat.
In particular, in the Documentation, to send the contents to the api, this code is used:
// swift
let snapImage = /* Set your image here */
let photo = SCSDKSnapPhoto(image: snapImage)
let snap = SCSDKSnapPhotoContent(snapPhoto: photo)
let api = SCSDKSnapAPI(content: snap)
api.startSnapping({ (error: Error?) in
/* Error handling */
})
According to the docs,
SCSDKPhotoSnapContent is an implementation of the SCSDKSnapContent protocol. It provides a way to model a photo Snap for sharing to Snapchat.
Here is my C# implementation:
var snapImage = GetCurrentScreenImage();
SCSDKSnapPhoto photo = new SCSDKSnapPhoto(snapImage);
SCSDKPhotoSnapContent snapPhoto = new SCSDKPhotoSnapContent(photo)
SCSDKSnapAPI api = new SCSDKSnapAPI(snapPhoto);
api.StartSnappingWithCompletionHandler((NSError error) =>
{
// Error handling
});
The problem is SCSDKSnapAPI constructor only accepts SCSDKSnapContent, which is an abstract class, and not its implementation, and I get an error calling it:
CS1503 Argument 1: cannot convert from 'SCSDKCreativeKit_Bindings.SCSDKPhotoSnapContent' to 'SCSDKCreativeKit_Bindings.SCSDKSnapContent'
EDIT:
ApiDefinition.cs
[Export("initWithContent:")]
IntPtr Constructor(SCSDKSnapContent content);
I tried adding another constructor like this:
[Export("initWithContent:SCSDKPhotoSnapContent")]
IntPtr Constructor(SCSDKPhtotoSnapContent content);
The code now builds, but I receive the following error code from SnapChat on callback:
SnapEncryptionMetadataUnexpectedStatusCode
I couldn't find a way to correctly implement SCSDKSnapContent in Xamarin.iOS. I did find a workaround, that sort of works. If you change constructor for SCSDKSnapAPI in the binding library from SCSDKSnapContent to one of its implementations (SCSDKPhotoSnapContent in my case), like this:
[Export("initWithContent:")]
IntPtr Constructor(SCSDKPhotoSnapContent content);
You can then correctly call SCSDKSnapAPI in Xamarin
var snapImage = GetCurrentScreenImage();
SCSDKSnapPhoto photo = new SCSDKSnapPhoto(snapImage);
SCSDKPhotoSnapContent snapPhoto = new SCSDKPhotoSnapContent(photo)
SCSDKSnapAPI api = new SCSDKSnapAPI(snapPhoto);
api.StartSnappingWithCompletionHandler((NSError error) =>
{
// Error handling
});

YouTrackSharp: can't get it to work

Trying to open an issue from a C# app.
Few issues:
1) UPDATE: I realize it only supports .NET Standard 1.3 = Framework 4.6; So no issue here.
2) I install version 2.0.31 (and less) - When I try to set up a connection, it says "Method not allowed":
var connection = new Connection("xxxx.myjetbrains.com", 80, false, "youtrack");
connection.Authenticate("xxxxx", "xxxxxx");
var issueManagement = new IssueManagement(connection);
dynamic issue = new Issue();
issue.Assignee = "xxxxx";
issue.ProjectShortName = "CV";
issue.Type = "Bug";
issue.Summary = "Test";
issue.Description = "Testing 1 2 3 ...";
issueManagement.CreateIssue(issue);
connection.Authenticate throws the error.
3) If I don't specify other parameters in Connection and leave only the basic url, I get the following error (again in connection.Authenticate):
For security reasons DTD is prohibited in this XML document. To enable
DTD processing set the DtdProcessing property on XmlReaderSettings to
Parse and pass the settings into XmlReader.Create method.
Can't seem to find much info on this online. Anyone has any idea what to do?
the 1.3 refers to .NETStandard - NOT .Net Framework. These are not the same thing.
You need .Net Framework 4.6 or up for .Net Standard 1.3 compatibility.
See here:
https://learn.microsoft.com/en-us/dotnet/standard/net-standard
I'd go directly to jetbrains for the other parts...
For anyone else getting stuck:
my YouTrack account was like this:
https://mycompanyname.myjetbrains.com/youtrack
Since it uses SSL (i.e. https) I had to mark the SSL parameter true instead of false, and mark port 443 instead of 80. Also I had to add the "youtrack" as a parameter. So the end result looks like this:
var connection = new Connection("xxxx.myjetbrains.com", 443, true, "youtrack");
connection.Authenticate("xxxx#xxxx.xxx", "xxxx");
I only had to do this in v.2, as I mentioned, v.3.0.0+ has working examples in their blog.

ASP.NET WebAPI 2.2 SPA with social login and no MVC dependencies

I have been designing an application which is just a statically served client page designed to use bearer tokens to authenticate with the backing API, however recently I have been trying to add social login options to the back-end but have found it very difficult to find any examples not using MVC dependencies which I would like to avoid if possible.
This question was a great help to get started: ASP.NET Web API social authentication for Web and Mobile
However I have been struggling to get my project to work in the same manor, basically in the question I referenced he has configured a OAuthAuthorizationServerOptions.AuthorizeEndpointPath like this:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/account/externallogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
//AllowInsecureHttp = false
};
Also in his backing api account controller he has the following action:
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
In this example I have not been able to figure out what the first parameter of the RouteAttribute (template) is actually referencing in the project, if anything, could someone maybe explain what it is doing in this context?
Now when running the sample project provided in the question sending a GET request to 'api/Account/ExternalLogin' the request will be handled on the action in his API account controller and I assume it has something to do with OverrideAuthentication but am getting a little out of my depth here and struggling to find strong examples of other usages of this attribute.
However I am fairly certain I have configured my WebAPI project correctly in the way he has described, however when sending a GET request to my OAuthAuthorizationServerOptions.AuthorizeEndpointPath it is not handled on my API account controller but instead by my implementation of OAuthAuthorizationServerProvider which returns a 'invalid_request' error.
Can anyone think of something that I might be overlooking which is causing my API account controller action to be ignored?
I also had a read through this article but it seems to have been written in an older version of WebAPI:
https://thompsonhomero.wordpress.com/2015/01/21/creating-a-clean-web-api-2-project-with-external-authentication-part-2/
Thanks for any help,
Alex.
Without actually seeing your GET requests that are being made, I can only assume that they do not meet expectations by the OAuth provider.
The provider first validates the request being made, THEN it hands control over to the endpoint's controller. Your code is most likely correct, it's just that the request is malformed.
I made a new project and was able to replicate the issue you describe by making a get request to the AuthorizeEndpointPath. Unfortunately, there's not much to go off of as to why, however if you decompile source, or manage to find the source, you can see what's going on here.
Decompiling the calling code of ApplicationOAuthProvider.ValidateClientRedirectUri I get:
await this.Options.Provider.ValidateClientRedirectUri(clientContext);
if (!clientContext.IsValidated)
{
LoggerExtensions.WriteVerbose(this._logger, "Unable to validate client information");
flag = await this.SendErrorRedirectAsync(clientContext, (BaseValidatingContext<OAuthAuthorizationServerOptions>) clientContext);
}
else
{
OAuthValidateAuthorizeRequestContext validatingContext = new OAuthValidateAuthorizeRequestContext(this.Context, this.Options, authorizeRequest, clientContext);
if (string.IsNullOrEmpty(authorizeRequest.ResponseType))
{
LoggerExtensions.WriteVerbose(this._logger, "Authorize endpoint request missing required response_type parameter");
validatingContext.SetError("invalid_request");
}
else if (!authorizeRequest.IsAuthorizationCodeGrantType && !authorizeRequest.IsImplicitGrantType)
{
LoggerExtensions.WriteVerbose(this._logger, "Authorize endpoint request contains unsupported response_type parameter");
validatingContext.SetError("unsupported_response_type");
}
else
await this.Options.Provider.ValidateAuthorizeRequest(validatingContext);
if (!validatingContext.IsValidated)
{
flag = await this.SendErrorRedirectAsync(clientContext, (BaseValidatingContext<OAuthAuthorizationServerOptions>) validatingContext);
}
else
{
this._clientContext = clientContext;
this._authorizeEndpointRequest = authorizeRequest;
OAuthAuthorizeEndpointContext authorizeEndpointContext = new OAuthAuthorizeEndpointContext(this.Context, this.Options, authorizeRequest);
await this.Options.Provider.AuthorizeEndpoint(authorizeEndpointContext);
flag = authorizeEndpointContext.IsRequestCompleted;
}
}
In this code, you can see that if the request has been validated and the request's specified ResponseType is not provided, it set's the context's error to "invalid_request".
I was able to get the request to go through to the ExternalLogin controller method successfully using the following request URI:
http://localhost:18086/api/Account/ExternalLogin?provider=none&client_id=self&redirect_uri=http://localhost:18086/&response_type=token`
P.S. As far as the route attribute on the controller, the "template" field specifies the string that will be used as a template to match incoming request URIs against to determine where the request should be routed.
P.P.S. Actual source code for the decompiled snippet can be found here

Sitecore LinkManager ExpandDynamicLinks does not resolve the site URL

I am having a problem with the ExpandDynamicLinks in Sitecore.
I am using the following method passing true for siteResolving. The problem is the site is not being resolved as promissed.
bodyExpandedLinks = Sitecore.Links.LinkManager.ExpandDynamicLinks(email.Body.Value, true);
I did set in my provider to never resolve the site because that is what I want for the whole site except for this email body above.
alwaysIncludeServerUrl="false"
Does anybody know how to force that?
Thank you...
I know this post is tagged with sitecore7, but I would like to share a solution for Sitecore 8.1. I don't know if it works for 7 or not. It is adapted from Sitecore.Links.LinkProvider.ExpandDynamicLinks():
var linkParser = new LinkProvider.LinkParser();
var urlOptions = LinkManager.Provider.GetDefaultUrlOptions(); // returns a clone.
urlOptions.SiteResolving = true;
urlOptions.AlwaysIncludeServerUrl = true;
text = linkParser.ExpandDynamicLinks(text, urlOptions);
This does not work for media links because Sitecore.Links.DynamicLink.BuildMediaUrl() and Sitecore.Links.MediaLinkExpander.Expand() completely ignore their UrlOptions parameter. If you need full media urls, wrap your code with this:
using (new SettingsSwitcher("Media.AlwaysIncludeServerUrl", "true"))
{
phrase = linkParser.ExpandDynamicLinks(phrase, urlOptions);
}
one option might be to check if AlwaysIncludeServerUrl is set to False before your call to ExpandDynamicLinks. If it's False you can explicitly call Sitecore.Links.UrlOptions.DefaultOptions.AlwaysIncludeServerUrl = true and then set it back to False after you have called ExpandDynamicLinks.
I found an alternative method.
I did add a extra link provider, with the same configurations but the alwaysIncludeServerUrl which I set to true.
<add name="sitecore_expandlinks" alwaysIncludeServerUrl="true" (...) >
Then I got the provider using the API.
bodyExpandedLinks = Sitecore.Links.LinkManager.Providers["sitecore_expandlinks"].ExpandDynamicLinks(email.Body.Value, true);
If someone else has a more cohesive option I would much appreciate
Thanks.

Acumatica Web Services API Login

I am attempting to perform some basic integration using Acumatica's web services. Unfortunatly, I'm having problems logging in. According to their documentation, this process should look something like:
apitest.Screen context = new apitest.Screen();
context.CookieContainer = new System.Net.CookieContainer();
context.AllowAutoRedirect = true;
context.EnableDecompression = true;
context.Timeout = 1000000;
context.Url = "http://localhost/WebAPIVirtual/Soap/APITEST.asmx";
LoginResult result = context.Login("admin", "E618");
Simple enough. However, after creating and importing a WSDL file from Acumatica into Visual Studio, I found I don't have a Screen object. I do, however have a ScreenSoapClient object, which has a similar Login() method.
ScreenSoapClient context = new Acumatica.ScreenSoapClient("ScreenSoap");
LoginResult result = context.Login("username", "password");
That part works. In fact, the LoginResult give me a session ID. However, if I try to make any calls to the service, such as:
CR401000Content cr401000 = context.CR401000GetSchema();
I get an error: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> PX.Data.PXNotLoggedInException: Error #185: You are not currently logged in.
While the version of Acumatica we're using does appear to be slightly newer, I'm unsure why the Screen() object isn't available. Consequently, if I try a bad username/password, Login() does fail (as it should). From what I can the tell, the ScreenSoapClient class is using service model details from web.config, so it's getting the endpoint address and other details there.
Is there something I'm missing or doing wrong?
As i see, you use WCF to create your service reference.
So you should enable cookies in service binding:
var binding = new BasicHttpBinding()
{
AllowCookies = true
};
var address = new EndpointAddress("http://localhost/WebAPIVirtual/Soap/APITEST.asmx");
var c = new ServiceReference1.ScreenSoapClient(binding, address);
Or, you can use old asmx web service reference (http://msdn.microsoft.com/en-us/library/bb628649.aspx).
Then everything will be same as in Acumatica`s documentation.
As noted in a comment above, I was able to make contact with a representative from Acumatica. He had me remove then recreate the service references in our project and try again. That apparently did the trick and the "Error #185: You are not currently logged in" error went away.

Categories