Does /templates route reserved for internal use in ServiceStack? - servicestack

Tried to write service to work with following RequestDTO
[Route("/templates", "POST", Summary = "Creates new template")]
public class CreateTemplate : IReturn<ExecutionResult>
{
public Guid TemplateId { get; set; }
public string Name { get; set; }
public string DefaultContent { get; set; }
}
But ServiceStack returns "Static File '/templates/' not found." As far as I can see /Templates folder can be used to define templates for /metadata. But I do not have such folder at all.

Related

ServiceStack - extending AutoQuery Metadata Viewer

ServiceStack's AutoQuery Viewer Plugin allows you to decorate the AutoQueries using AutoQuery metadata attributes. I use the existing Metadata service in AutoQuery to power a front-end and display search queries (similar to the existing AutoQuery Admin Feature)
How can I extend/ add additional properties to the AutoQueryViewerAttribute, such that they are available in the Autoquery metadata service?
Current list of AutoQuery attributes available:
public class AutoQueryViewerAttribute : AttributeBase
{
public string Title { get; set; }
public string Description { get; set; }
public string IconUrl { get; set; }
public string BrandUrl { get; set; }
public string BrandImageUrl { get; set; }
public string TextColor { get; set; }
public string LinkColor { get; set; }
public string BackgroundColor { get; set; }
public string BackgroundImageUrl { get; set; }
public string DefaultSearchField { get; set; }
public string DefaultSearchType { get; set; }
public string DefaultSearchText { get; set; }
public string DefaultFields { get; set; }
}
I would like to extend the list of AutoQueryViewerAttribute attributes and add two additional properties:
public string SourceDescription { get; set; }
public string SourceApplicationName { get; set; }
You can't extend the [AutoQueryViewer] attribute which is hard coded. The Info on the Attribute is used to populate the Typed AutoQueryMetadataResponse DTO which is what's serialized to provide the AutoQuery metadata services. I've just added Meta String Dictionaries on the MetadataType, AutoQueryViewerConfig, AutoQueryViewerUserInfo, AutoQueryOperation and AutoQueryMetadataResponse DTO in this commit so you can attach additional metadata to the AutoQuery metadata DTOs using the MetadataFilter, e.g:
Plugins.Add(new AutoQueryMetadataFeature {
MetadataFilter = response => {
response.Meta = new Dictionary<string,string> {
{ "SourceApplicationName", "My App" },
{ "SourceDescription", "My App Description" },
};
}
});
This change is available from v4.5.13 that's now available on MyGet.

Custom Azure API Apps for Files

I'm looking to create some custom API apps for the sole purpose of creating a/some Logic Apps. With these custom API Apps, I want to pass around files. These files will usually be CSV, ZIP, Excel, TXT, and some other formats - unknown to the consumer until the file is returned (i.e. the client does not dictate the file format).
How does one do something like this in a way that's compatible with Swagger/Swashbuckle, Web API, and Logic Apps? I'll ultimately be tying this into an FTP connector, Dropbox, Onebox, or other file-storage connector.
Does following something like this work or do I need to take a different approach? For example, should I simply work with JSON objects and let my binary be base64-encoded by using a model like this?
public class BinaryFile
{
public string FileName { get; set; }
public string FileExtension { get; set; }
public string DeducedMimeType { get; set; }
public int FileSize { get; set; }
public string FileEncoding { get; set; }
public byte[] FileBinary { get; set; }
}
(this question is cross-posted to MSDN Forums)
The approach I've taken is what I posed in the question with the BinaryFile class. I've broken it out into a few classes. I'm not done - I have some improvements to make still but this is functional right now.
Main class with some common fields:
public class FileResult<T>
{
public string Source { get; set; }
public T File { get; set; }
public IList<string> ErrorMessages { get; set; } = new List<string>();
public bool IsSuccessful { get; set; } = false;
}
This is the <T> in my FileResult<T> class:
public class CsvFile
{
public string Filename { get; set; }
public string Contents { get; set; }
public int Size { get; set; }
}
public class BinaryFile
{
public string FileName { get; set; }
public string FileExtension { get; set; }
public string DeducedMimeType { get; set; }
public int Size { get; set; }
public byte[] Contents { get; set; }
}
Note that in my case, there are some times when I am working with multiple files and not just one, so what could appear to be some common fields are still within the type passed in as the <T> so I can have something like FileResult<IEnumerable<CsvFile>>.
This is all playing nicely with Swagger, Swashbuckle, Web API, Azure API Apps, and Azure Logic Apps. For the cases where I am returning multiple files to my Azure Logic App, I use the fairly hidden splitsOn feature (that also has some designer bugs, so be careful!) to easily iterate over all of the files. It works very nicely.

What's the best way to convey required/optional DTO properties in ServiceStack?

I'm having an issue with my ServiceStack w/ Swagger implementation regarding documenting required/optional properties. Developers implementing clients that consume my services love the Swagger documentation, however they don't know which properties are required vs. optional--aside from getting a 400 response on each attempt to get a valid request through.
Take the following example:
public class UserProfile
{
public string FirstName { get; set; }
public string LastName { get; set; }
public UserAddress Address { get; set; }
}
public class UserAddress
{
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
}
Swagger will cleanly show both of these types if they are part of my DTO, however I can't convey that FirstName, LastName, or any of the Address properties are required or not. Is there a way to accomplish this without having to roll a separate spec document?
You can use an [ApiMember(IsRequired = false)] attribute on the properties in the DTO to add extra information for swagger ui.
There is list of the attributes that swagger ui will recognise on the servicestack wiki

Parsing YouTube Json for Windows Store apps

I generate C# Class from http://json2csharp.com/ for any YouTube URL, in which some names are invalid like as follows:
public class Feed
{
public string __invalid_name__xmlns$media { get; set; }
public string __invalid_name__gd$etag { get; set; }
}
In the above code actual Youtube name is xmlns$media, gd$etag like that...
when I change those to:
public class Feed
{
public string xmlns$media { get; set; }
public string gd$etag { get; set; }
}
in C# it shows error because of special character $, If I don't use $ parsing doesn't happens and returns Null.
Help me fixing this!
Does this work for you?
[DataContract]
public class Feed
{
[DataMember(Name="xmlns$media")]
public string xmlns_media { get; set; }
[DataMember(Name="gd$etag")]
public string gd_etag { get; set; }
}

ServiceStack RazorRockstars Example - Reserved Route?

I have an issue with the RazorRockstars example. I have renamed the main route (/rockstars) on the Rockstars request class to /properties and now it no longer loads. It appears /properties route is reserved. Is this the case? I wish to use this route in my application.
Works:
[Route("/rockstars")]
[Route("/rockstars/{Id}")]
[Route("/rockstars/aged/{Age}")]
public class Rockstars
{
public int? Age { get; set; }
public int Id { get; set; }
}
Works:
[Route("/blahblahblah")]
[Route("/blahblahblah/{Id}")]
[Route("/blahblahblah/aged/{Age}")]
public class Rockstars
{
public int? Age { get; set; }
public int Id { get; set; }
}
Does not work:
[Route("/properties")]
[Route("/properties/{Id}")]
[Route("/properties/aged/{Age}")]
public class Rockstars
{
public int? Age { get; set; }
public int Id { get; set; }
}
Using /properties doesn't work in development because it matches a folder in your root directory (which hi-jacks the request), i.e. in this case VS.NET's Properties/ folder it uses to hold your projects AssemblyInfo.cs file.
It will work after you rename the Properties folder to something else, or once you deploy since deployment builds doesn't include the Properties folder.

Resources