ServiceStack POST 空体的招摇 [英] Swagger for ServiceStack POST empty body

查看:13
本文介绍了ServiceStack POST 空体的招摇的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 )在上个月内,所以我认为它在 Nuget 下载中不可用.

  • 您看到的是一个空的正文,因为您的 DTO 上的每个属性的 ParameterType 都是正文".Swagger 想要一个包含整个请求正文内容的正文"值.它不会循环遍历您的每个正文"属性来组成正文内容.如果您填充 Rating 文本框,您应该会在请求中看到它的值(Rating 是您的最后一个带有 'body' ParameterType 的属性).

  • 在此处查看示例 http://petstore.swagger.wordnik.com/#!/pet/addPet_post_1

    使用 Chrome 或 Firebug,您可以在 swagger-ui.js 中的第 1182 行周围设置断点,以查看它如何构建请求正文内容(bodyParam 变量)

    I'm having some problems with the Swagger plugin to ServiceStack. I have configured the route descriptions for my service, but the resulting POST does not contain a body.

    My Service looks like this:

    /// <summary>
    /// Define your ServiceStack web service request (i.e. Request DTO).
    /// </summary>
    /// <remarks>The route is defined here rather than in the AppHost.</remarks>
    [Api("GET or DELETE a single movie by Id. Use POST to create a new Movie and PUT to update it")]
    [Route("/movie", "POST", Summary = @"POST a new movie", Notes = "Send a movie here")]
    [Route("/movie/{Id}", "GET,PUT,DELETE", Summary = @"GET, PUT, or DELETE a movie", Notes = "GET a specific movie by Id, or PUT a thing, or delete a movie")]
    public class Movie
    {
        /// <summary>
        /// Initializes a new instance of the movie.
        /// </summary>
        public Movie()
        {
            this.Genres = new List<string>();
        }
    
        /// <summary>
        /// Gets or sets the id of the movie. The id will be automatically incremented when added.
        /// </summary>
        //[AutoIncrement]
        [ApiMember(Name = "Id", Description = "The Id of this movie", ParameterType = "body", DataType = "string", IsRequired = false)]
        public string Id { get; set; }
    
        [ApiMember(Name = "ImdbId", Description = "The ImdbId of this movie", ParameterType = "body", DataType = "string", IsRequired = false)]
        public string ImdbId { get; set; }
    
        [ApiMember(Name = "Title", Description = "The Title of this movie", ParameterType = "body", DataType = "string", IsRequired = false)]
        public string Title { get; set; }
    
        [ApiMember(Name = "Rating", Description = "The Rating of this movie", ParameterType = "body", DataType = "decimal", IsRequired = false)]
        public decimal Rating { get; set; }
    
        [ApiMember(Name = "Director", Description = "The Director of this movie", ParameterType = "string", DataType = "string", IsRequired = false)]
        public string Director { get; set; }
    
        [ApiMember(Name = "ReleaseDate", Description = "The ReleaseDate of this movie", ParameterType = "string", DataType = "Date", IsRequired = false)]
        public DateTime ReleaseDate { get; set; }
    
        [ApiMember(Name = "TagLine", Description = "The TagLine of this movie", ParameterType = "string", DataType = "string", IsRequired = false)]
        public string TagLine { get; set; }
    
        [ApiMember(Name = "Genres", Description = "The Genres of this movie", ParameterType = "string", DataType = "string", IsRequired = false)]
        public List<string> Genres { get; set; }
    }
    
    /// <summary>
    /// Define your ServiceStack web service response (i.e. Response DTO).
    /// </summary>
    public class MovieResponse
    {
        /// <summary>
        /// Gets or sets the movie.
        /// </summary>
        public Movie Movie { get; set; }
    }
    
    /// <summary>
    /// Create your ServiceStack restful web service implementation. 
    /// </summary>
    public class MovieService : Service
    {
        public IMovieRepository MovieRepository { get; set; }
    
        /// <summary>
        /// GET /movies/{Id} 
        /// </summary>
        public MovieResponse Get(Movie movie)
        {
            var item = MovieRepository.FindOne(new ObjectId(movie.Id));
    
            return new MovieResponse
            {
                Movie = item,
            };
        }
    
        /// <summary>
        /// POST /movies
        /// 
        /// returns HTTP Response => 
        ///     201 Created
        ///     Location: http://localhost/ServiceStack.MovieRest/movies/{newMovieId}
        ///     
        ///     {newMovie DTO in [xml|json|jsv|etc]}
        /// 
        /// </summary>
        public object Post(Movie movie)
        {
            MovieRepository.Save(movie);
            var newMovieId = movie.Id;
    
            var newMovie = new MovieResponse
            {
                Movie = MovieRepository.FindOne(new ObjectId(movie.Id))
            };
    
            return new HttpResult(newMovie)
            {
                StatusCode = HttpStatusCode.Created,
                Headers = {
                    { HttpHeaders.Location, base.Request.AbsoluteUri.CombineWith(newMovieId) }
                }
            };
        }
    
        /// <summary>
        /// PUT /movies/{id}
        /// </summary>
        public object Put(Movie movie)
        {
            MovieRepository.Save(movie);
    
            return new HttpResult
            {
                StatusCode = HttpStatusCode.NoContent,
                Headers = {
                    { HttpHeaders.Location, this.RequestContext.AbsoluteUri.CombineWith(movie.Id) }
                }
            };
        }
    
        /// <summary>
        /// DELETE /movies/{Id}
        /// </summary>
        public object Delete(Movie request)
        {
            MovieRepository.Remove(new ObjectId(request.Id));
    
            return new HttpResult
            {
                StatusCode = HttpStatusCode.NoContent,
                Headers = {
                    { HttpHeaders.Location, this.RequestContext.AbsoluteUri.CombineWith(request.Id) }
                }
            };
        }
    }
    
    /// <summary>
    /// Define your ServiceStack web service request (i.e. Request DTO).
    /// </summary>
    /// <remarks>The route is defined here rather than in the AppHost.</remarks>
    [Api("Find movies by genre, or all movies if no genre is provided")]
    [Route("/movies", "GET, OPTIONS")]
    [Route("/movies/genres/{Genre}")]
    public class Movies
    {
        public string Genre { get; set; }
    }
    
    /// <summary>
    /// Define your ServiceStack web service response (i.e. Response DTO).
    /// </summary>    
    public class MoviesResponse
    {
        /// <summary>
        /// Gets or sets the list of movies.
        /// </summary>
    
        public List<Movie> Movies { get; set; }
    }
    
    /// <summary>
    /// Create your ServiceStack RESTful web service implementation. 
    /// </summary>
    public class MoviesService : Service
    {
        public IMovieRepository MovieRepository { get; set; }
    
        /// <summary>
        /// GET /movies 
        /// GET /movies/genres/{Genre}
        /// </summary>
        public object Get(Movies request)
        {
            return new MoviesResponse
            {
                Movies = MovieRepository.FindAll().ToList()
            };
        }
    }
    

    The Swagger interface appears to have picked up the elements correctly:

    The results is a 500 error:

    POST http://localhost:57853/movie HTTP/1.1
    Host: localhost:57853
    Connection: keep-alive
    Content-Length: 0
    Accept: application/json, text/javascript, */*; q=0.01
    Origin: http://localhost:57853
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
    Content-Type: application/json
    Referer: http://localhost:57853/swagger-ui/index.html
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-GB,en;q=0.8,en-US;q=0.6
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    

    The POST body is not attached by Swagger. The Content-Length:0. The results is an empty request object, which results in a NullReferenceException.

    Can anyone see anything that I am doing wrong?

    解决方案

    A couple issues I see...

    • I think you're trying to mimic a Form post using Swagger-UI. This feature was just added to swagger (https://github.com/wordnik/swagger-core/issues/69) within the last month so I don't think it's available in the Nuget download.

    • You're seeing an empty body because your ParameterType is 'body' for each Property on your DTO. Swagger wants a single 'body' value which should contain the entire request body contents. It is not looping through each of your 'body' properties to compose the body contents. If you populate the Rating text box you should see it's value in the request (Rating is your last property with 'body' ParameterType).

    see example here http://petstore.swagger.wordnik.com/#!/pet/addPet_post_1

    Using Chrome or Firebug you can set a breakpoint around line #1182 in swagger-ui.js to see how it's building up the request body contents (bodyParam variable)

    这篇关于ServiceStack POST 空体的招摇的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆