OpenApi (Redoc) remote (network) nested references - c#

We have a running Redoc server, which includes a bunch on yaml files with api specifications. However, a couple of neccesary yaml files are not on the local (let's call it RedocServer) machine.
Those remote files are accessible through aspnet-webapi service (WebApiServer).
So, let's say, to get one of those files, we use refernce in the index.yaml file:
paths:
/api/1:
$ref: "https:/some-address/ApiDoc.yaml"
If ApiDoc.yaml itself has no refences, there is no problem for WebApiServer to simply return a string using a method like that:
[HttpGet]
public string GetApiDoc()
{
var directoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var filePath = Path.Combine(directoryPath, "ApiDoc.yaml");
return File.ReadAllText(filePath);
}
However, in our case, that ApiDoc.yaml has some huge, nested references to another files inside it. Something like that, implying that referenced objects have references inside them:
post:
tags:
- Test
summary: Test
operationId: Test
consumes:
- application/json
produces:
- application/json
requestBody:
content:
application/json:
schema:
$ref: "../ApiDoc2.yaml#/components/schemas/ApiRequest"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "../ApiDoc3.yaml#/components/schemas/ApiResponse"
If WebApiServer returns a string like that, RedocServer will probably just try to resolve these references with RedocServer files. But we obviously want to make sure that refernces will be resolved on the WebApiServer side.
So, the question is, how to properly return that ApiDoc.yaml without breaking any references?
We cannot resolve references manually because objects are huge and deeply nested. OpenApi.net, which we tried to use, still isn't able to resolve remote references automatically, and also doesnt't seem to be able to work with files without "info" and "openapi:3.0.0" part in it.

As it turns out, Redoc automatically parses remote references, replacing local path in urls with remote url.
So simply put: you can just return a string or file like that, and everything should be working all right.

Related

Domino Objects COMException: 'Out of memory'

When I call NotesDXLExporterClass.Export on a NotesDocumentClass object that has a very large attachment, I get a System.Runtime.InteropServices.COMException: 'Out of memory' exception.
I was hoping to resolve this by setting NotesDXLExporter.OmitRichtextAttachments to true, but it looks like this property is not available through COM (1).
What are my options here to get around this issue?
(1) Differences between accessing Domino Objects through either LotusScript or COM
Note 4: NotesXMLProcessor is not implemented in COM. NotesDXLExporter and NotesDXLImporter implement ExitOnFirstFatalError, Log, and LogComment, rather than inheriting them. )
Edit:
When I open C:\Program Files (x86)\IBM\Lotus\Notes\domobj.tlb in Oleview.exe and look at the NotesDXLExporterClass interface I only see the following:
[
uuid(29131437-2EED-1069-BF5D-00DD011186B7)
]
dispinterface NOTESDXLEXPORTER {
properties:
[id(0x00000bf6)
]
VARIANT FORCENOTEFORMAT;
[id(0x00000bfa)
]
VARIANT OUTPUTDOCTYPE;
[id(0x00000bfb)
]
BSTR DOCTYPESYSTEM;
[id(0x00000f1e), readonly
]
BSTR LOG;
[id(0x00000f1f)
]
BSTR LOGCOMMENT;
[id(0x00000f20)
]
VARIANT EXITONFIRSTFATALERROR;
methods:
[id(0x00000f28)]
void SETINPUT(VARIANT INPUT);
[id(0x00000f29)]
void SETOUTPUT(VARIANT OUTPUT);
[id(0x00000f2a)]
void PROCESS();
};
The document to which you've linked (and also my local Notes Help) doesn't say that NotesDXLExporter.OmitRichtextAttachments isn't available in COM. Did you try using that property and get an error?
If NotesDXLExporter.OmitRichtextAttachments isn't available, are you able to develop an agent in the relevant Domino database (or in another database created for this purpose) that acts as a go-between?
I'm thinking an agent could take the note id of the target document via NotesAgent.Run, and export that document's DXL to a field (which might have to be rich text if the DXL is more than 32kB) in another temporary document. Your code should call that agent via COM, get the resulting temporary document, read the DXL from its field, then delete the temporary document.
This seems overly complex, but it's the only solution that occurs to me.
Try running your code as a LotusScript agent.
If it fails, the problem is inherent in the classes, not in the COM implementation and there's not going to be much you can do other than trying a more up-to-date version of Notes/Domino.
If it works, a potential workaround would be to have your COM code invoke a LotusScript agent on the server to do this part of the work.

WebApi - How to include relative paths for included App_Data XML files?

Question Background:
I have a WebApi controller who's logic code relies on reading data contained in a number of XML files. These XML files have been included in the App_Data folder of the WebApi project.
The Issue:
I'm trying to use the relative path of the XML files in the following way:
[System.Web.Http.HttpGet]
public string CallerOne()
{
string docOne = #"~\AppData\DocOne.xml";
string poll = #"~\AppData\Poll.xml";
var response = _Caller.CallService(docOne, poll);
return ConvertXmlToJson(response);
}
When running the WebApi code and calling the Url to the CallerOne method I receive the following error:
An exception of type 'System.IO.DirectoryNotFoundException'
occurred in System.Xml.dll but was not handled in user code
Additional information: Could not find a part of the path
'C:\Program Files (x86)\IIS Express\~\AppData\FPS.xml'.
I also want to eventually publish this to Azure and include these files.
How can I use the relative path to read in the XML files in the App_Data folder?
Ended up finding the answer.
The following is needed to read the relative paths in a WebApi project:
var fullPath = System.Web.Hosting.HostingEnvironment.MapPath(#"~/App_Data/yourXmlFile.xml");
As jdweng inferred several months back, Environment.GetEnvironmentVariable("AppData") would seem to be the preferred method. The OP's auto-accepted answer and that give quite different results. For example, using both of those in my project, I get:
C:\\Projects\\PlatypusReports\\PlatypusReports\\App_Data\\yourXmlFile.xml
...for the OP's long-winded code, namely this:
var fullPath = System.Web.Hosting.HostingEnvironment.MapPath(#"~/App_Data/yourXmlFile.xml");
...and this:
C:\\Users\\cshannon\\AppData\\Roaming
...for jdweng's code, to wit:
string appData = Environment.GetEnvironmentVariable("AppData");
OTOH, this code:
string appDataFolder = HttpContext.Current.Server.MapPath("~/App_Data/");
returns:
C:\\Projects\\PlatypusReports\\PlatypusReports\App_Data\
So it's very similar in results (if not methodology) to the first example above. I actually got it from a question I asked almost two years ago, which I had forgotten about.
I'm not positive if jdweng's approach would work as expected once the app is deployed on a server, but I have much more confidence in it than the other approaches.
Can anyone verify?
UPDATE
The accepted answer here has 237 upvotes at time of typing, so seems pretty reliable, albeit 6 years old (42 in dog years, which may be a good sign).
Your approach is fine. You just had some tpying error,
You wrote
string docOne = #"~\AppData\DocOne.xml";
But it should have been
string docOne = #"~\App_Data\DocOne.xml";

LibGit2Sharp get repository changes after pull

How can i get the following information after a git-pull with libgit2sharp:
Which files has been moved
Which files has been created
Which files has been deleted
The git-pull request it self works perfectly:
var result = repo.Network.Pull(new LibGit2Sharp.Signature("admin", "mail#......net", new DateTimeOffset(DateTime.Now)), options);
I already looked at the result of the Pull-Method, but this seems not to contain the needed information.
Thank you very much!
The MergeResult type exposes a Commit property which is not null when the merge was successful.
In order to find out what files have changed, one just have to leverage the repo.Diff.Compare() method to compare this Commit with its first parent.

BizTalk Dynamic Disassembler Problems - The body part is NULL

I started with the solution here http://social.technet.microsoft.com/wiki/contents/articles/20547.biztalk-server-dynamic-schema-resolver-real-scenario.aspx
which matches my scenario perfectly except for the send port, but that isn't necessary. I need the receive port to choose the file and apply a schema to disassemble. From their the orchestration does the mapping, some of it custom, etc.
I've done everything in the tutorial but I keep getting the following error.
"There was a failure executing the receive pipeline... The body part is NULL"
The things I don't get from the tutorial but don't believe they should be an issue are:
I created a new solution and project to make the custompipeline component (reference figure 19) and thus the dll file. Meaning it is on it's own namespace. However, it looks like from the tutorial they created the project within the main biztalk solution (ie the one with the pipeline and the orchestration) and thus the namespace has "TechNetWiki.SchemaResolver." in it. Should I make the custompipeline component have the namespace of my main solution? I'm assuming this shouldn't matter because I should be able to use this component in other solutions as it is meant to be generic to the business rules that are associated with the biztalk application.
The other piece I don't have is Figure 15 under the "THEN Action" they have it equal the destination schema they would like to disassemble to but then they put #Src1 at the end of "http://TechNetWiki.SchemaResolver.Schemas.SRC1_FF#Src1". What is the #Src1 for?
In the sample you've linked to, the probe method of the pipeline component is pushing the first 4 characters from the filename into a typed message that is then passed into the rules engine. Its those 4 characters that match the "SRC1" in the example.
string srcFileName = pInMsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties This link is external to TechNet Wiki. It will open in a new window. ").ToString();
srcFileName = Path.GetFileName(srcFileName);
//Substring the first four digits to take source code to use to call BRE API
string customerCode = srcFileName.Substring(0, 4);
//create an instance of the XML object
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(string.Format(#"<ns0:Root xmlns:ns0='http://TechNetWiki.SchemaResolver.Schemas.SchemaResolverBRE This link is external to TechNet Wiki. It will open in a new window. '>
<SrcCode>{0}</SrcCode>
<MessageType></MessageType>
</ns0:Root>", customerCode));
//retreive source code in case in our cache dictionary
if (cachedSources.ContainsKey(customerCode))
{
messageType = cachedSources[customerCode];
}
else
{
TypedXmlDocument typedXmlDocument = new TypedXmlDocument("TechNetWiki.SchemaResolver.Schemas.SchemaResolverBRE", xmlDoc);
Microsoft.RuleEngine.Policy policy = new Microsoft.RuleEngine.Policy("SchemaResolverPolicy");
policy.Execute(typedXmlDocument);
So the matching rule is based on the 1st 4 characters of the filename. If one isn't matched, the probe returns a false - i.e. unrecognised.
The final part is that the message type is pushed into the returned message - this is made up of the namespace and the root schema node with a # separator - so your #src1 is the root node.
You need to implement IProbeMessage near to class
I forgot to add IProbeMessage in the code of article. It is updated now.
but it is there in sample source code
Src1 is the the root node name of schema. I mentioned that in article that message type is TargetNamespace#Root
I recommend to download the sample code
I hope this will help you

web.config in asp.net

I've got the function for changing the values in web.config
but my problem is it is not getting the path of web.config correctly and throwing
"Could not find file 'C:\Users\maxnet25\Web.config'"
It was giving error on xmlDoc.Load() function.
My code:
public void UpdateConfigKey(string strKey, string newValue)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config");
if (!ConfigKeyExists(strKey))
{
throw new ArgumentNullException("Key", "<" + strKey + "> not find in the configuration.");
}
XmlNode appSettingsNode = xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode childNode in appSettingsNode)
{
if (childNode.Attributes["key"].Value == strKey)
childNode.Attributes["value"].Value = newValue;
}
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config");
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
Label1 .Text ="Key Upated Successfullly";
}
What error messsage is being given?
Either way, you're not really going about modifying web.config in the right way. You should probably take a look at the System.Configuration.ConfigurationManager class as this provides programmatic access to the web.config file in a structured manner. Note that to access this class you need to add a reference to System.Configuration.dll to your project to bring the ConfigurationManager into scope.
If you look at the example code for the GetSection method, it shows how to create/add settings in the appSettings section of a .net config file, so that example should be enough to get you where you want to go.
If you definately want to use this approach to manipulate your web.config file, I suspect that:
AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config")
is incorrect, based on the path that you've shown in the error message. Try removing the ..\..\ and seeing if that works. AppDomain.CurrentDomain.BaseDirectory should be pointing at the location of your web.config file without modification.
Assuming this is indeed an ASP.NET website, instead of this:
AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config"
Use this:
HttpContext.Current.Server.MapPath("~/Web.config")
On a side note, please be aware that anytime you make a change to web.config, your web application restarts. You might not need to worry about that depending on what your web app does though.
Try using Server.MapPath() to resolve the location of your web.config. If you're in a page, Server is one of the page properties. If not, you can find it in HttpContext.Current.
As an example...
HttpContext.Current.Server.MapPath("~/web.config")
...should return the physical path to the web.config at the top of your web application.
Now, you're probably much better off using the WebConfigurationManager, as shown in this post. The approach is much cleaner, but requires a reference to System.Configuration.
Have you added a web.config to your web site?
You should use either:
System.Configuration.ConfigurationManager
for app.config files, or:
System.Web.Configuration.WebConfigurationManager
for web.config files.
You can actually use System.Configuration.ConfigurationManager with web.config files as well, and to be honest, I'm not actually sure if there's any benefit for using one over the other.
But either way, you should not be using the Xml namespaces and writing/modifying the raw XML.

Categories

Resources