Swashbuckle parameter descriptions - c#

I'm using SwaggerResponse attributes to decorate my api controller actions, this all works fine, however when I look at the generated documentation the description field for parameters is empty.
Is a there an attribute based approach to describe action parameters (rather than XML comments)?

With the latest Swashbuckle, or better said at least the Swashbuckle.AspNetCore variant which I'm using, the Description field for parameters can now be displayed correctly as output.
It does require the following conditions to be met:
XML comments must be enabled and configured with Swagger
Parameters should be explicitly decorated with either [FromRoute], [FromQuery], [FromBody] etc.
The same for the method type (get/post/put etc.), which should be decorated with [Http...]
Describe the parameter as usual with a <param ...> xml comment
A full sample looks like this:
/// <summary>
/// Short, descriptive title of the operation
/// </summary>
/// <remarks>
/// More elaborate description
/// </remarks>
/// <param name="id">Here is the description for ID.</param>
[ProducesResponseType(typeof(Bar), (int)HttpStatusCode.OK)]
[HttpGet, Route("{id}", Name = "GetFoo")]
public async Task<IActionResult> Foo([FromRoute] long id)
{
var response = new Bar();
return Ok(response);
}
Which produces the following output:

You should confirm you are allowing Swagger to use XML comments
httpConfig.EnableSwagger(c => {
if (GetXmlCommentsPath() != null) {
c.IncludeXmlComments(GetXmlCommentsPath());
}
...
...
);
protected static string GetXmlCommentsPath() {
var path = HostingEnvironment.MapPath("path to your xml doc file");
return path;
}
You should also check you are generating XML doc for your desired project. Under your desired project Properties (Alt + Enter on top of the project or Right Click -> Properties) -> Build -> Check XML documentation file

For completeness sake, when using latest version of Swashbuckle.AspNetCore (2.1.0) and Swashbuckle.SwaggerGen/Ui (6.0.0), enable Xml documentation file generation in your project's Build
Then the following to your ConfigureServices() method:
services.ConfigureSwaggerGen(options =>
{
options.SingleApiVersion(new Info
{
Version = "v1",
Title = "My API",
Description = "API Description"
});
options.DescribeAllEnumsAsStrings();
var xmlDocFile = Path.Combine(AppContext.BaseDirectory, $"{_hostingEnv.ApplicationName}.xml");
if (File.Exists(xmlDocFile))
{
var comments = new XPathDocument(xmlDocFile);
options.OperationFilter<XmlCommentsOperationFilter>(comments);
options.ModelFilter<XmlCommentsModelFilter>(comments);
}
});

Related

Check the method in project

I am trying to debug code from https://nunrar.codeplex.com/. In branch DOCUMENTATION -> Basic Usage there is the following code:
RarArchive archive = RarArchive.Open(source);
foreach (RarArchiveEntry entry in archive.Entries)
{
string path = Path.Combine(destination, Path.GetFileName(entry.FilePath));
entry.ExtractToFile(path);
}
Well.. I 've downloaded source code, find RarArchiveEntry class and started to looking for method ExtractToFile(), but there isn't any method there neither in class, nor in project!
Please help me to find this method or method which i can call to look through how this programm can unpack rar files step-by-step?
It looks like the documentation is obsolete and the name of the method was changed, there is an extension method found in RarArchiveEntry.Exensions.cs called WriteToFile.
/// <summary>
/// Extract to specific file
/// </summary>
public static void WriteToFile(this RarArchiveEntry entry, string destinationFileName, ExtractOptions options = ExtractOptions.Overwrite)
{
entry.WriteToFile(destinationFileName, new NullRarExtractionListener(), options);
}

Displaying the full name with Enums and resource file in c# MVC

Giving this one more try
I have an Enums.cs file where I have the following code
public enum AuthorizingLevels
{
[Display(Name = "AuthorizingLevels_SysSupport", ResourceType = typeof(Resources.Enums))]
SysSupport
}
And when I try calling it to display the Name, it doesn't work
ViewBag.AuthGroupFullName = Enums.AuthorizingLevels.SysSupport.ToString();
It just displays the SysSupport instead of the full name Systems Support
I went to a link provided in my previous question (How to get the Display Name Attribute of an Enum member via MVC razor code?) and added the code by Peter Kerr
/// <summary>
/// A generic extension method that aids in reflecting
/// and retrieving any attribute that is applied to an `Enum`.
/// </summary>
public static string GetDisplayName(this Enum enumValue)
{
var displayAttrib = enumValue.GetType()
.GetMember(enumValue.ToString())
.First()
.GetCustomAttribute<DisplayAttribute>();
var name = displayAttrib.Name;
var resource = displayAttrib.ResourceType;
return String.IsNullOrEmpty(name) ? enumValue.ToString()
: resource == null ? name
: new ResourceManager(resource).GetString(name);
}
However, I get an error on the line
: new ResourceManager(resource).GetString(name);
An exception of type 'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll but was not handled in user code
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Resources.Enums.resources" was correctly embedded or linked into assembly "FWS" at compile time, or that all the satellite assemblies required are loadable and fully signed.
The resource file is the right one minus the .resources at the end... not sure if that should be there or not.
What am I doing wrong? I'm learning MVC and c# as I go so any help would be greatly appreciated.
Thank you
Try this. It is fairly hacky but it should hopefully give you what you need. I use Assembly.GetExecutingAssembly().GetManifestResourceNames() to get the names of all the resources in the executing assembly and then I attempt to match the file up correctly using some linq. If it finds a file that looks ok, a new ResourceManager is created as you were using in your original code.
/// <summary>
/// A generic extension method that aids in reflecting
/// and retrieving any attribute that is applied to an `Enum`.
/// </summary>
public static string GetDisplayName(this Enum enumValue)
{
var displayAttrib = enumValue.GetType()
.GetMember(enumValue.ToString())
.First()
.GetCustomAttribute<DisplayAttribute>();
var name = displayAttrib.Name;
if (String.IsNullOrEmpty(name))
{
return enumValue.ToString();
}
else
{
var resource = displayAttrib.ResourceType;
if (resource != null)
{
var resources = Assembly.GetExecutingAssembly().GetManifestResourceNames()
.Where(x => x.EndsWith(String.Format("{0}.resources", resource.Name)))
.Select(x => x.Replace(".resources", string.Empty)).ToList();
if (resources.Any())
{
return new ResourceManager(resources.First(), Assembly.GetExecutingAssembly()).GetString(name);
}
}
return name;
}
}

solr pdf extraction works but no indexing

I working with solr to extract pdf files and index it. now I am able to extract it with the following code:
private static void IndexPDFFile(ISolrOperations<Article> solr)
{
string filecontent = null;
using (var file = File.OpenRead(#"C:\\cookbook.pdf"))
{
var response = solr.Extract(new ExtractParameters(file, "abcd1")
{
ExtractOnly = true,
ExtractFormat = ExtractFormat.Text,
});
filecontent = response.Content;
}
solr.Commit();
}
but when I check solr with the following command in the browser, nothing appears:
http://berserkerpc:444/solr/select/?q=text:solr
or
http://berserkerpc:444/solr/select/?q=author:admin
the content of the pdf file is: This is a Solr cookbook...
the field author should contain somethinh with admin.
here the output:
<response><lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params"><str name="q">text:Solr</str></lst></lst><result name="response" numFound="0" start="0"/></response>
any suggestions for that issue??
thanks,
tro
This is because you have set the ExtractOnly=true in your ExtractParameters. Here is the comment for the ExtractOnly parameter from the source code.
/// <summary>
/// If true, return the extracted content from Tika without indexing the document.
/// This literally includes the extracted XHTML as a string in the response.
/// </summary>
public bool ExtractOnly { get; set; }
If you want to index the extracted content, do not set this parameter to true.

Default values for arguments in rehosted WF4 designer fail to parse

The results from a rehosted designer (WF4) have an issue when adding a default value to an argument. Every other case seems to work fine. This is the (abridged) xaml of a (nearly) empty workflow.
<Activity mc:Ignorable="sap" x:Class="{x:Null}" this:_b40c.NewArg="test" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:this="clr-namespace:" xmlns:twc="clr-namespace:Telogis.Workflow.CustomerApi;assembly=Telogis.Workflow.Activities"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="AuthenticationHeader" Type="InArgument(twc:AuthenticationHeader)" />
<x:Property Name="BaseTdeUri" Type="InArgument(x:Uri)" />
<x:Property Name="NewArg" Type="InArgument(x:String)" />
</x:Members>
<sap:VirtualizedContainerService.HintSize>654,676</sap:VirtualizedContainerService.HintSize>
<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
<Flowchart />
</Activity>
Specifically when default value is added, the following additions are made to the definition: this:_b40c.NewArg="test" and xmlns:this="clr-namespace:"
xmlns:this="clr-namespace:" is invalid as it doesn't point anywhere and can't be parsed with ActivityXamlServices.Load(stream); (it throws XamlObjectWriterException: "'Cannot set unknown member '{clr-namespace:}_b40c.NewArg'.' ...)
This seems to occur whatever the specified type of the argument is.
Any idea what could be causing this?
Update
I was using an ActivityBuilder to utilise the activity in the first place. This was fine, but as I hadn't provided it with a name, it had to generate a key, in the example above _b40c. ActivityXamlServices.Load has some kind off issue processing these keys. However, simply defining a name for ActivityBuilder seems to do the trick.
This still doesn't answer why it creates xmlns:this="clr-namespace:" without an actual namespace.
Your workflow xaml is invalid. I'm not sure where you got it or how it got into this state.
I can tell this because
<Activity
x:Class="{x:Null}"
this:_b40c.NewArg="test"
xmlns:this="clr-namespace:"
the clr-style namespace declaration is invalid. It should read
clr-namespace:Some.Namespace.In.The.Current.Assembly
or
clr-namespace:Some.Namespace;assembly=SomeAssemblyWithSomeNamespace
As your declaration is malformed, the this xml namespace cannot be parsed by the XamlObjectWriter in order to determine what namespace/assembly your _b40c type exists in. Also, that looks highly suspicious as well. And I've never seen an x:Class set to null before. That also strikes me as malformed.
If I understand well - this is WF Designer bug.
I've faced with this problem when I had had to support default value definition for InArgument<T> in my custom WF designer. I still surprised lack of support for this basic procedure.
There are 2 reason of failure:
Definition of {x:Null} in x:Class attribute
Invalid definition of xmlns:this attribute
And the main problem is invalid definition of Argument's default value: this:_effe.MyArgument="asd". The definition of default value for argument should be equal to this:MyXamlClassName.MyArgument="asd". For example, if your x:Cass definition is x:Class="MyNamespace.MyClass", Argument definition should be this:MyClass.MyArgument="asd".
I resolved it by intervention into XAML saving process:
After calling of
_workflowDesigner.Save(_editedFile);
I added these two lines:
#region x:Class and Argument<T> default value issues solution
await CreateAttributeValue(_editedFile, ConstXClassAttributeName, typeof(App).Namespace + "." + Path.GetFileNameWithoutExtension(_editedFile));
//should finish first operation before second operation begins to avoid I/O exception
await CreateAttributeValue(_editedFile, ConstNamespaceAttributeName, ConstXamlClrNamespace + typeof(App).Namespace);
await RepairArgsAttributes(_editedFile);
#endregion
This is the methods definition:
/// <summary>
/// Reason of using of this method: bug in workflow designer. When you save your xaml file, WF Designer assign "{x:Null}" to x:Class attribute
/// Bug: In addition, if you want to set default value for your InArgument<T>, it defines attribute "this" (namespace declaration) with empty value. When you try to open your file, designer fails to parse XAML.
/// </summary>
/// <param name="editedFile"></param>
/// <param name="attribteName"></param>
/// <param name="attributeValueToReplace"></param>
private static async Task CreateAttributeValue(string editedFile, string attribteName, string attributeValueToReplace)
{
XmlDocument xmlDoc = new XmlDocument();
await Task.Run(() => xmlDoc.Load(editedFile));
await Task.Run(() =>
{
var attributteToReplace = xmlDoc.FirstChild.Attributes?[attribteName];
if (null != attributteToReplace)
{
xmlDoc.FirstChild.Attributes[attribteName].Value = attributeValueToReplace;
xmlDoc.Save(editedFile);
}
});
}
/// <summary>
/// Bug in Workflow designer: workflow designer saves declaration for In/Out Arguments in invalid format. Means, that it is unable to open the same file it saved itself. This method fixes the Arguments declaration in XAML xmlns
/// </summary>
/// <param name="editedFile"></param>
/// <returns></returns>
private async Task RepairArgsAttributes(string editedFile)
{
XmlDocument xmlDoc = new XmlDocument();
await Task.Run(() => xmlDoc.Load(editedFile));
await Task.Run(() =>
{
for (int i = 0; i < xmlDoc.FirstChild.Attributes.Count; i++)
{
if (xmlDoc.FirstChild.Attributes[i].Name.StartsWith(ConstInvalidArgStarts))
{
string innvalidAttrName = xmlDoc.FirstChild.Attributes[i].Name;//extraction of full argument declaration in xmlns
string[] oldStrings = innvalidAttrName.Split('.');//extraction of arguemnt name string
string localName = Path.GetFileNameWithoutExtension(editedFile) + "." + oldStrings[1];//build valid argment declaration without perfix
string valueBackup = xmlDoc.FirstChild.Attributes[i].Value;//saving of default value of Arguemnt<T>
xmlDoc.FirstChild.Attributes.RemoveNamedItem(xmlDoc.FirstChild.Attributes[i].Name);//removal of invalid Arguemnt declaration with default value. WARNING: when you remove attribue, at this moment you have another item at the place xmlDoc.FirstChild.Attributes[i]
//definition of new valid attribute requries: set separelly attribute prefix, localName (not "name" - it causes invalid attribute definition) and valid namespace url (in our case it's namespace deifinition in "this")
XmlAttribute attr = xmlDoc.CreateAttribute(ConstArgPrefix, localName, xmlDoc.FirstChild.Attributes[ConstNamespaceAttributeName].Value);
attr.Value = valueBackup;
xmlDoc.FirstChild.Attributes.InsertBefore(attr, xmlDoc.FirstChild.Attributes[i]);//define new correct Argument declaration attribute at the same place where was invalid attribute. When you put valid attribute at the same place your recover valid order of attributes that was changed while removal of invalid attribute declaration
}
}
xmlDoc.Save(editedFile);
});
}
The constants definition are:
#region Constants
private const string ConstXClassAttributeName = "x:Class";
private const string ConstXamlClrNamespace = "clr-namespace:";
private const string ConstNamespaceAttributeName = "xmlns:this";
private const string ConstInvalidArgStarts = #"this:_";
private const string ConstArgPrefix = #"this";
#endregion
This solution should resolve your issue too.

Is there any API for presenting normalized data after a query is made from linq?

For example Service Stack does this to with the Northwind database:
http://www.servicestack.net/ServiceStack.Northwind/customers/ALFKI?format=html
Is there anything that reads the database structure and relationships and output a report based on a primary id?
Obviously, I am looking into alternatives to servicestack.
I use LINQPad's .Dump() object visualizer for that. Download LINQPad from http://www.linqpad.net and reference the .exe in your project.
You will then have access to LINQPads .CreateXhtmlWriter() that can output a beautiful object graph visualization:
just by going:
var listOfItems = DataContext.Items.ToList();
listOfItems.Dump();
The following is not my code, but I cannot find the origin, so bear with me.
Use extension method to create the Xhtml dump and show it a browser:
public static class LinqPadExtensions
{
/// <summary>
/// Writes object properties to HTML
/// and displays them in default browser.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="o"></param>
/// <param name="heading"></param>
public static void Dump<T>(
this T o,
string heading = null
)
{
string localUrl =
Path.GetTempFileName() + ".html";
using (
var writer =
LINQPad.Util.CreateXhtmlWriter(true)
)
{
if (!String.IsNullOrWhiteSpace(heading))
writer.Write(heading);
writer.Write(o);
File.WriteAllText(localUrl, writer.ToString());
}
Process.Start(localUrl);
}
}

Categories