Why adding ApiExplorer breaks Swashbuckle? - asp.net-core-webapi

After I added
services.AddVersionedApiExplorer();
previously normally working Swashbuckle started showing blank Swagger json with default version and no endpoints in it.

It appears that ApiExplorer requires presence of ApiControllerAttribute at API controllers. So if you don't have your controllers decorated with this attribute, everything will work perfectly up to the point when you add ApiExplorer, and after that Swachbuckle will behave like there are no controllers in your project at all (apparently, that's what ApiExplorer tells it).
Decorating your controllers with [ApiController] fixes this issue.
In case you don't want to bother with writing RegExp to apply those changes for you, or even go into every single controller file to paste it manually, [assembly:ApiController] will handle all of them at once.

Related

How can I override Request class?

I tried overriding the core classes but this one doesnt seem to work. I know I will need to update the application/config/app.php file to point to the new class. But when I do this the HTML redender stops at head tag.
I extended the Request Class from core to application/src, updated the app.php file, but it doest work and gives me a blank page. I will need this to use redirect url.
if your goal is to do something to the request before sending it back you might want to use a middleware instead of overriding the class.
A good example is the Centry portal package which you can find here: https://github.com/a3020/centry
Have a look at centry\Provider\CentryServiceProvider.php function registerMiddleware() to see how to register a middleware.
And then look at the 2 files in centry\Http\Middleware to see how it's used.
If you are using version 8 you will need to autoload your classes in the src folder.
In application/bootstrap/autoload.php
$classLoader = new \Symfony\Component\ClassLoader\Psr4ClassLoader();
$classLoader->addPrefix('Application\\Example', DIR_APPLICATION . '/' . DIRNAME_CLASSES . '/Example');
From here you will need to override the associated service provider. It's not entirely clear which class you are trying to override and which service provider this would require. Below is an example for overriding the \Concrete\Core\Http\HttpServiceProvider with class placed in application/Src/Example/HttpServiceProvider
return [
'providers' => [
'core_http' => 'Application\Example\HttpServiceProvider'
]
]
From the service provider you can extend classes and override the returned classes in a way the suits your use case scenario (It can be tedious if multiple classes have references but it's the only way I'm aware of to properly override core classes). Typically you can just extend existing classes overriding a single method or two and come up with an elegant solution.

Django Rest Framework render_form & required fields

When using HTML form renderer in DRF, can anyone think of a nice way to auto generate some indication of "required" field in DRF, by hook or crook? I mean before I submit the form, some indication on the field that it is required - the Browsable API it will show right in the form what the error is but only after submitting.
Whether I am using technique as shown here for browseable API with field level HTML forms (instead of just raw/JSON form):
django-rest-framework - autogenerate form in browsable API?
Or I am using TemplateHTMLRenderer with a call to render_form as discussed in docs here:
http://www.django-rest-framework.org/topics/html-and-forms/#rendering-forms
I don't see a simple way to make my required fields rendered as required. So say we have like
#models.py
class Foobar(model.Models):
foo = models.CharField(max_length=100, blank=True, default='')
bar = models.CharField(max_length=100, blank=False)
The best I can think of is making my own template/snippet for each type of field "required-text-field.html", "required-checkbox.html", etc and using the style declaration in the serializer as shown here:
http://www.django-rest-framework.org/topics/html-and-forms/#field-styles
That's assuming I am understanding this, have not played with it yet to see.
But I would love to see a way to auto-generate the field with/without a required flag as appropriate (even just an asterisk, or applying a CSS class) based on the model definition.
Rambling: The goal here was to avoid writing my own forms, having DRF generate the form for me in custom views. As opposed to writing my own forms using tying them into AJAX I figured templates, render_form, and some format checks would suffice. But now I'm thinking DRF is built for back-end and dev, not front-end, and maybe I should plan to write my own forms if it will be end-user visible? Also I could have CSS files and select based on name, calling render_form then applying hand spun styles, would be less work than the HTML + the CSS. Should I review Django (just Django, not DRF) Forms and re-use serializer as validation?...
I can see 2 ways:
you can define your own template pack, look at the existing ones in the sources (e.g. 'rest_framework/horizontal/input.html') - you can check if field is required and according to this flag, set some css. you do not need something extra, especially "input-readonly.html" - just make your own copy of input.html, add few if-s and it will work.
or you can call OPTIONS on the API endpoint to get all the necessary information about fields, not only required, but readonly and allowed values for some selects - this is if you can update your forms from javascript

Trying to override templates in FOSUserBundle, but having no effect

I'm trying to modify the skin of the register.html.twig template found in FOSUserBundle/Resources/views/Registration/register.html.twig.
I've basically followed the instructions in the documentation down to a T.
Like it told to do so, I created /app/Resources/views/FOSUserBundle/views/Registration/register.html.twig.
Cleared the cache (and browser cache just to be sure)
NO effect! I've put a blank file in register.html.twig, but no matter what I put there, when I go to /register/, I still see the default template.
Yep, these things happen all the time.
It should be:
/app/Resources/FOSUserBundle/views/Registration/register.html.twig
Reference

How to access pretty URL from code

I am using UrlRewriteFilter to make my URLs pretty. From within my application I frequently need to access the current URL. I do it like this:
ServletActionContext.getRequest().getRequestURI();
However this gives me the ugly version of the URL. How can I access the pretty URL before it is turned into ugly one by UrlRewriteFilter?
You can extend the URLRewriteFilter class and override the doFilter method to store the request path in request attribute (Use this attribute to access the pretty url). Later call the super.doFilter method to let URLRewriteFilter do its job.
I have found this solution here.
This worked for me:
ServletActionContext.getRequest().getAttribute(
"javax.servlet.forward.request_uri");

asp.net mvc how to manage urls/links and routing centrally (c# + js)

I keep running into problems with URLs and routing.
Couldn't find an answer on SO.
I would like to manage all of my urls/links in a single place.
This is for my C# MVC code and the js/jquery ajax code.
These urls are scattered throughout my application.
Moving to a production server needs some fixes and I don't like the fact that I need to look for all of the occurrences in the application.
I don't mind fixing this once - but I would like to do it only once.
Any ideas how to manage all of these links/urls as a group will be very appreciated.
Be happy ad enjoy life, Julian
Consider using T4MVC
You could use Html.ActionLink or
Html.BuildUrlFromExpression(c => c.ControllerAction())
Depends, if you have application reading off certain urls and those urls changed once in a while. then you might want to consider putting all those urls into a database table/etc and retrieve them using specific key.
that way, when your url changed, all you need to do is to change the url on your database and all your application will still be running fine.
Urls should be managed in a single place: the RegisterRoutes static method in Global.asax. In absolutely every other part of your application you should use Html helpers when dealing/generating urls. This way you will never have problems because helpers take into account your routing system.
So instead of writing:
$('#foo').click(function() {
$('#result').load('/mycontroller/myaction');
return false;
});
you use an HTML helper to generate this foo:
<%: Html.Action("foo", "myaction", "mycontroller") %>
and then:
$('#foo').click(function() {
$('#result').load(this.href);
return false;
});
Never hardcode a single url in your application except of course in global.asax which is the only centralized place urls should be defined. So basically every time you find yourself writing something of the form /foo/bar in some other part than global.asax you are doing it wrong.

Resources