Giter Site home page Giter Site logo

Comments (16)

FreakyJ avatar FreakyJ commented on June 27, 2024 5

I recently had the same problem and solved it with an OperationFilter:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Swashbuckle.SwaggerGen.Generator;

namespace MediaPortal.Plugins.AspNetServer
{
    public class HandleModelbinding : IOperationFilter
  {
    public void Apply(Operation operation, OperationFilterContext context)
    {
      if (operation.Parameters == null) return;

      foreach (IParameter param in operation.Parameters)
      {
        if (param.In == "modelbinding")
          param.In = "query";
      }
    }
  }
}

domaindrivendev is probably right, that one should be more precise, but I think it is a lot of extra code just for making the query string working.

from swashbuckle.aspnetcore.

ericwj avatar ericwj commented on June 27, 2024 4

So you decided to break model binding. Swaggers job is to generate schema, not impose your opinion of good design, imho

It'd be much more useful to make the schema valid and warn lets say in the Swagger UI, perhaps even only if IHostingEnvironment.IsDevelopment()

Unless you also designed an easy way for the developer to make that error go away, have modelbinding work and generate valid Swagger.

And I mean really, really easy, so no requirements of implementing a filter or so. Lets say by e.g. setting a single property on the options in one of the add/use calls in Startup services.AddSwagger(options => options.DefaultParameterLocation = LocationEnum.FromQuery); or something like that. (Off topic: whats a Gen?)

from swashbuckle.aspnetcore.

domaindrivendev avatar domaindrivendev commented on June 27, 2024 3

Technically, there's nothing in your code that's explicitly calling those parameters out as query string parameters. In fact (and I've just tested this), they could also be sent in the body as form data:

POST /api/security/login HTTP/1.1
Host: localhost:5054
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

username=foob&password=bar

This opens up your API to being used in a way you didn't actually intend - probably harmless in this case but still something I would advise against. In addition, this ambiguity will confuse self-documenting tools like Swashbuckle because they can't be certain which way is the "correct" way. So, I would recommend being more explicit with your parameter bindings:

[HttpPost]
[Route("Login")]
public void Login([FromQuery]string userName, [FromQuery]string password)

from swashbuckle.aspnetcore.

jlehew avatar jlehew commented on June 27, 2024 1

"in":"modelbinding" in the swagger.json file generally means the parameter attribute is missing. I generally search the swagger.json file for modelbinding to find the signatures I need to fix.

Here's an example of what the problem looks like in swagger.json

    "parameters": [
      {
        "name": "folderid",
        "in": "modelbinding",

In C# for example, had to add [FromBody], folderid was required and would compile without a [FromRoute] attribute.

    [HttpGet("{folderid}")]
    public IActionResult GET( Int64 folderid, [FromBody] APICall callvalue)

Also look for an optional parameter specified in the Http Attribute with a question mark:

    [HttpGet("{folderid?}")]
    public IActionResult GET( [FromRoute] Int64 folderid)

Optional parameters require the [FromRoute] attribute. When I added this attribute the swagger.json updated to:

    "parameters": [
      {
        "name": "folderid",
        "in": "path",

And AutoRest was able to code generate the client successfully.

Since this is an issue with developer code and it is not possible for a tool to determine developer intentions, there isn't much that can be done except to add a better error message IMO. If the tool defaults to Query or Route, it may not line up with how the code needs to work causing downstream issues instead of pointing to the source of the problem.

John

from swashbuckle.aspnetcore.

ericwj avatar ericwj commented on June 27, 2024 1

Well... It does guess. And it produces invalid swagger as a result. "in": "modelbinding" is just plain non-sense - that's my argument.

How would you feel if your favorite web server software framework would start spitting out random HTML tags due to some issue with your code that you didn't detect? How would that render in the browser? That's what is happening here.

If I make an error of the same kind with any other tool or technology, if my project at all builds, the site just crashes at startup. Or I get HTTP 500's.. That'd be much easier to test as well.

E.g. if my database connection string is wrong, or I reference a file that doesn't exist.

from swashbuckle.aspnetcore.

mjrousos avatar mjrousos commented on June 27, 2024

Since ASP.NET web APIs support parameters that can be passed in multiple ways, I think it would make sense to have Swashbuckle handle that scenario and do the modelbinding->query mapping automatically.

A lot of people starting out with ASP.NET Core may not specify explicit parameter-in values for their parameters and will be confused if Swashbuckle-generated swagger is invalid for those APIs.

from swashbuckle.aspnetcore.

ericwj avatar ericwj commented on June 27, 2024

That "modelbinding" value is not a valid option in Swagger 2.0.

Field Name Type Description
in string Required. The location of the parameter. Possible values are "query", "header", "path", "formData" or "body".

Is the idea that you are championing it to be included in the 2.0 spec or a future version?

from swashbuckle.aspnetcore.

mjrousos avatar mjrousos commented on June 27, 2024

I think the best option would be to automatically apply a filter that @FreakyJ is using. Ideally, API authors would be clearer about how parameters should be passed. But if they aren't, I think it would make sense for Swashbuckle to just pick a way (@FreakyJ uses query) so that the generated swagger is valid.

from swashbuckle.aspnetcore.

ericwj avatar ericwj commented on June 27, 2024

I agree on the ideal world - adding the flexibility to the Swagger spec leads to a host of issues, but convention over configuration is the best option I think. Ahoy actually knows in is allowed to be query where it sais modelbinding now, so it could just pick that as a default to be at least valid, unless there is a filter to override that behaviour.

Would the parameter need to be secured, the author has to specify an option that'd be encrypted over SSL after seeing it being padded to the URL...

Putting some invalid string in the swagger is fairly bad...I had AutoRest crash over it.

from swashbuckle.aspnetcore.

domaindrivendev avatar domaindrivendev commented on June 27, 2024

A general question: If you only want to document "one way" of passing an API parameter why would you want the API to support alternatives?

An API is a contract and like any contract, ambiguity introduces risk. If you want a consumer to use an operation in a specific way then just be explicit and type the extra 10 or so characters. If you don't do this, you're increasing the surface area of your API meaning more ways for consumers to become coupled and hence making your implementation more difficult to change. You're also leaving future developers of your API left to wonder what exactly was the original intended interaction for these operations.

But alas, if the overwhelming opinion is to continue supporting this practice of ambiguous API design, then I'm left with no choice but to introduce these defaults you're all asking for :)

from swashbuckle.aspnetcore.

ericwj avatar ericwj commented on June 27, 2024

I like model binding. Just not in Swagger 2.0 ;)

Conceptually, perhaps it'd be worth to move (or rather, mimic) the Swagger behaviour to (or near) compile time by means of a Roslyn analyzer? Just so there would be warnings upon build for this kind of issues.

That'd be far better than generating invalid Swagger or picking a default that doesn't reflect the API. I mean, model binding still works whatever the Swagger schema sais right? And you're quite right that has its own problems in terms of spec vs use and maintainability etc - the prime violator perhaps being the original developer of the API...

The tricky part might be to faithfully warn/break the build considering the actual Swashbuckle configuration in effect at the time of build, short of actually running the fully configured generator.

from swashbuckle.aspnetcore.

domaindrivendev avatar domaindrivendev commented on June 27, 2024

It's worth noting that the next release (already overdue) will raise a runtime error instead of returning invalid Swagger. Compile time would be ideal but might take considerable effort. I think the runtime error is acceptable. Being part of the product, I would hope that some form of testing (automated or otherwise), even a quick smoke test, is carried out on the generated docs.

from swashbuckle.aspnetcore.

domaindrivendev avatar domaindrivendev commented on June 27, 2024

@jlehew - I completely agree that a tool of this nature should not attempt to guess the developers intentions and that a more informative error message is the right path forward.

These are added with 9bf2cb4 and will be available in with the 6.0.0 release

from swashbuckle.aspnetcore.

domaindrivendev avatar domaindrivendev commented on June 27, 2024

Good man ... as per my last comment, this will be handled by informative error messages and these are already in master, pending release.

@ericwj - thanks for your understanding & support to this OS project which I provide to the community with many personal hours and zero financial gain

from swashbuckle.aspnetcore.

ericwj avatar ericwj commented on June 27, 2024

Ah yes, thanks - I should have said I will be looking forward to the 6.0.0 release

Your time and effort is appreciated! Ahoy has certainly been a great addition for .NET Core projects

from swashbuckle.aspnetcore.

domaindrivendev avatar domaindrivendev commented on June 27, 2024

Available with latest pre-release. Note the package rename to "Swashbuckle.AspNetCore.1.0.0-rc1"

from swashbuckle.aspnetcore.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.