This commit is contained in:
stankovski 2015-02-20 16:32:44 -08:00
Родитель 6956fe3d17
Коммит ef67574d4f
25 изменённых файлов: 1456 добавлений и 2 удалений

36
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
*.bmp binary
*.dll binary
*.gif binary
*.jpg binary
*.png binary
*.snk binary
*.exe binary
*.wmv binary
*.mp4 binary
*.ismv binary
*.isma binary
*.ascx text
*.cmd text
*.config text
*.cs text diff=csharp
*.csproj text merge=union
*.edmx text
*.htm text
*.html text
*.js text
*.json text
*.msbuild text
*.nuspec text
*.resx text
*.ruleset text
*.StyleCop text
*.targets text
*.txt text
*.xml text
*.sln text eol=crlf merge=union

120
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,120 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
developer/
# Build results
binaries/
[Dd]ebug*/
[Rr]elease/
build/
[Tt]est[Rr]esult
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# Code analysis
*.CodeAnalysisLog.xml
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Publish Web Output
*.Publish.xml
# Others
[Bb]in
[Oo]bj
sql
TestResults
[Tt]est[Rr]esult*
*.Cache
ClientBin
[Ss]tyle[Cc]op.*
~$*
*.dbmdl
*.[Pp]ublish.xml
# Build tasks
tools/*.dll
# Sensitive files
*.keys
*.pfx
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
# NuGet
packages
# Mac development
.DS_Store
build.out

3
Documentation/README.md Normal file
Просмотреть файл

@ -0,0 +1,3 @@
# Documentation #
TODO: Add documentation

Просмотреть файл

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015 Microsoft Azure
Copyright (c) 2015 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

149
README.md
Просмотреть файл

@ -1 +1,148 @@
# AutoRest
# AutoRest #
----------
The AutoRest tool generates client libraries for accessing RESTful web services described by a [Swagger](http://github.com/swagger-api/swagger-spec) documentation file.
The project is open-source on GitHub at [https://github.com/Azure/AutoRest](https://github.com/Azure/AutoRest).
[TOC]
##Hello World##
For the AutoRest version of Hello World, we will look at three distinct parts: the REST API that returns a greeting, the Swagger spec that documents the API, and the code for using the client library that AutoRest generates.
### RESTful HelloWorld ###
Here is a trivial ASP.Net Web API that returns a string.
```
public class HelloWorldController : ApiController
{
// GET: api/HelloWorld
public string Get()
{
return "Hello via AutoRest.";
}
}
```
### Swagger HelloWorld ###
Swagger is written in JSON. The spec must conform to the [Swagger schema](https://raw.githubusercontent.com/swagger-api/swagger-spec/master/schemas/v2.0/schema.json).
Let's put together a minimal spec to document the service.
Every Swagger spec starts with a field declaring the version of Swagger being used. AutoRest supports version 2.0.
```
{
"swagger": "2.0"
```
The `info` object is required. The two required fields are title and version.
AutoRest uses the title as the class name of the generated client library.
```
"info": {
"title": "Client01",
"version": "1.0.0"
},
```
Next, we include the name of the host. The Swagger schema doesn't require the host. If it is not provided, it is assumed that the document is being retrieved from the host that also serves the API. In the following examples, we include the host explicitly. The value can specify the hostname or ip address and a port value if needed.
```
"host": "swaggersample.azurewebsites.net",
```
The `paths` object is a collection of individual paths and details about the operations, parameters, and responses.
```
"paths": {
...
}
```
The HelloWorld operation is exposed at
```
"/api/HelloWorld": {
```
The HelloWorld API only defined one operation. It is using the GET verb.
```
"get": {
```
We also include an `operationId` . The value is used by AutoRest to name the methods generating for accessing this endpoint with this verb. The Swagger schema itself does not require `operationId` but without it, automatically provisioned names can become too long or too generic.
```
"operationId": "GetGreeting",
```
Next, we document the mime types that the operation returns. Here, we are just specifying that we expect a JSON result.
```
"produces": [
"application/json"
],
```
Swagger allows specifying different types of responses per HTTP status code. For HelloWorld, we expect a 200 ("OK") and just a string. It is required by the Swagger schema that the response definition include a description. AutoRest uses it in the generated code as comments for the method. In Visual Studio, they are visible as tooltips.
```
"responses": {
"200": {
"description": "GETs a greeting.",
"schema": {
"type": "string"
}
}
}
```
Because we haven't defined any other status codes or provided a `default` response schema, the AutoRest-generated client will throw an exception if the response it gets is not a 200 OK.
By convention, Swagger documents are exposed by web services with the name `swagger.json`. Here, we are using a naming convention to make it easier to keep track of multiple examples. The title from the `info` object is *Client01* and we put it all together in a file named *swagger01.json* that looks like this:
```
{
"swagger": "2.0",
"info": {
"title": "Client01",
"version": "1.0.0"
},
"host": "swaggersample.azurewebsites.net",
"paths": {
"/api/HelloWorld": {
"get": {
"operationId": "GetGreeting",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "GETs a greeting.",
"schema": {
"type": "string"
}
}
}
}
}
}
}
```
### AutoRest HelloWorld ###
We created the HelloWorld web service, and then we documented it using the Swagger format in `swagger01.json`. Now, we will use AutoRest to generate client code to and use it from a sample app.
We'll use a console application project called SampleApp for examples. The only thing unique about this project is that we have installed the *"Microsoft.Rest.ClientRuntime"* package. The code generated by AutoRest has a dependency on this package. More details on it later.
> Install-Package Microsoft.Rest.ClientRuntime
AutoRest is extensible and can support multiple types of input and output. **AutoRest.exe** comes with the *AutoRest.json* configuration file that defines the available inputs (*Modelers*) and outputs (*CodeGenerators*). At preview, only the CSharp code generator and Swagger modeler are available.
Besides the *Modeler* and *CodeGenerator*, several other parameters are passed to AutoRest. The *BaseNamespace* for AutoRest to use must be provided. The Swagger schema itself is language agnostic and doesn't include the notion of namespace, but for generating code, it is specified explicitly. The *OutputFolder* parameter is not required but used in the examples. If not present, the *CodeGenerator* decides where to put the output. By default, a directory named Generated* is created for the output.
>AutoRest.exe -CodeGenerator CSharp -Modeler Swagger -Input swagger01.json
>-BaseNamespace AutoRest01 -OutputFolder Generated
The code was generated into a subdirectory of the SampleApp. You can either explicitly add the generated files to the project. While iterating on Swagger files, I modify the .csproj file to include all the generated code.
```
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Client01\*.cs" />
<Compile Include="Client01\Models\*.cs" />
</ItemGroup>
```
We included the code directly into the project. In practice, you would likely generate clients into their own reusable library projects. For looking at a set of examples, consuming the code directly is convenient. We need a using statement for the namespace of the generated code.
```
using AutoRest01;
```
Ignoring the fact that `GetGreeting` will throw an exception if the response is not a 200 OK, we can access the REST API with very little code.
```
Console.WriteLine(new Client01().GetGreeting().Body);
```
Running the console app shows the greeting retrieved from the service API.
>C:\\>SampleApp.exe
>Hello via AutoRest.
With that same basic pattern in place, we can explore how different REST API operations and payloads are described in Swagger and exposed in the code generated by AutoRest.

Просмотреть файл

@ -0,0 +1,204 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using AutoRest01;
using AutoRest01.Models;
using Microsoft.Rest;
using Newtonsoft.Json.Linq;
namespace AutoRest01
{
public partial class Client01 : ServiceClient<Client01>, IClient01
{
private Uri _baseUri;
/// <summary>
/// The base URI of the service.
/// </summary>
public Uri BaseUri
{
get { return this._baseUri; }
set { this._baseUri = value; }
}
/// <summary>
/// Initializes a new instance of the Client01 class.
/// </summary>
public Client01()
: base()
{
this._baseUri = new Uri("http://swaggersample.azurewebsites.net");
}
/// <summary>
/// Initializes a new instance of the Client01 class.
/// </summary>
/// <param name='handlers'>
/// Optional. The set of delegating handlers to insert in the http
/// client pipeline.
/// </param>
public Client01(params DelegatingHandler[] handlers)
: base(handlers)
{
this._baseUri = new Uri("http://swaggersample.azurewebsites.net");
}
/// <summary>
/// Initializes a new instance of the Client01 class.
/// </summary>
/// <param name='rootHandler'>
/// Optional. The http client handler used to handle http transport.
/// </param>
/// <param name='handlers'>
/// Optional. The set of delegating handlers to insert in the http
/// client pipeline.
/// </param>
public Client01(HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
: base(rootHandler, handlers)
{
this._baseUri = new Uri("http://swaggersample.azurewebsites.net");
}
/// <summary>
/// Initializes a new instance of the Client01 class.
/// </summary>
/// <param name='baseUri'>
/// Optional. The base URI of the service.
/// </param>
/// <param name='handlers'>
/// Optional. The set of delegating handlers to insert in the http
/// client pipeline.
/// </param>
public Client01(Uri baseUri, params DelegatingHandler[] handlers)
: this(handlers)
{
if (baseUri == null)
{
throw new ArgumentNullException("baseUri");
}
this._baseUri = baseUri;
}
/// <param name='cancellationToken'>
/// Cancellation token.
/// </param>
public async Task<GetGreetingOKResponseResult> GetGreetingAsync(CancellationToken cancellationToken)
{
// Tracing
bool shouldTrace = ServiceClientTracing.IsEnabled;
string invocationId = null;
if (shouldTrace)
{
invocationId = ServiceClientTracing.NextInvocationId.ToString();
Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
ServiceClientTracing.Enter(invocationId, this, "GetGreetingAsync", tracingParameters);
}
// Construct URL
string url = "";
url = url + "/api/HelloWorld";
string baseUrl = this.BaseUri.AbsoluteUri;
// Trim '/' character from the end of baseUrl and beginning of url.
if (baseUrl[baseUrl.Length - 1] == '/')
{
baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
}
if (url[0] == '/')
{
url = url.Substring(1);
}
url = baseUrl + "/" + url;
url = url.Replace(" ", "%20");
// Create HTTP transport objects
HttpRequestMessage httpRequest = null;
try
{
httpRequest = new HttpRequestMessage();
httpRequest.Method = HttpMethod.Get;
httpRequest.RequestUri = new Uri(url);
// Set Headers
// Send Request
HttpResponseMessage httpResponse = null;
try
{
if (shouldTrace)
{
ServiceClientTracing.SendRequest(invocationId, httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
httpResponse = await this.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
if (shouldTrace)
{
ServiceClientTracing.ReceiveResponse(invocationId, httpResponse);
}
HttpStatusCode statusCode = httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
if (statusCode != HttpStatusCode.OK)
{
HttpOperationException ex = HttpOperationException.Create(httpRequest, null, httpResponse, responseContent);
if (shouldTrace)
{
ServiceClientTracing.Error(invocationId, ex);
}
throw ex;
}
// Create Result
GetGreetingOKResponseResult result = new GetGreetingOKResponseResult();
// Deserialize Response
if (statusCode == HttpStatusCode.OK)
{
result = new GetGreetingOKResponseResult();
JToken responseDoc = null;
if (string.IsNullOrEmpty(responseContent) == false)
{
responseDoc = JToken.Parse(responseContent);
}
if (responseDoc != null)
{
result.DeserializeJson(responseDoc);
}
}
result.StatusCode = statusCode;
if (shouldTrace)
{
ServiceClientTracing.Exit(invocationId, result);
}
return result;
}
finally
{
if (httpResponse != null)
{
httpResponse.Dispose();
}
}
}
finally
{
if (httpRequest != null)
{
httpRequest.Dispose();
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AutoRest01;
using AutoRest01.Models;
namespace AutoRest01
{
public static partial class Client01Extensions
{
/// <param name='operations'>
/// Reference to the AutoRest01.IClient01.
/// </param>
public static GetGreetingOKResponseResult GetGreeting(this IClient01 operations)
{
return Task.Factory.StartNew((object s) =>
{
return ((IClient01)s).GetGreetingAsync();
}
, operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
}
/// <param name='operations'>
/// Reference to the AutoRest01.IClient01.
/// </param>
public static Task<GetGreetingOKResponseResult> GetGreetingAsync(this IClient01 operations)
{
return operations.GetGreetingAsync(CancellationToken.None);
}
}
}

Просмотреть файл

@ -0,0 +1,31 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AutoRest01.Models;
namespace AutoRest01
{
public partial interface IClient01 : IDisposable
{
/// <summary>
/// The base URI of the service.
/// </summary>
Uri BaseUri
{
get; set;
}
/// <param name='cancellationToken'>
/// Cancellation token.
/// </param>
Task<GetGreetingOKResponseResult> GetGreetingAsync(CancellationToken cancellationToken);
}
}

Просмотреть файл

@ -0,0 +1,51 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using Microsoft.Rest;
using Newtonsoft.Json.Linq;
namespace AutoRest01.Models
{
public partial class GetGreetingOKResponseResult : HttpOperationResponse
{
private string _body;
/// <summary>
/// Optional.
/// </summary>
public string Body
{
get { return this._body; }
set { this._body = value; }
}
/// <summary>
/// Initializes a new instance of the GetGreetingOKResponseResult class.
/// </summary>
public GetGreetingOKResponseResult()
{
}
/// <summary>
/// Deserialize the object
/// </summary>
public override void DeserializeJson(JToken inputObject)
{
base.DeserializeJson(inputObject);
if (inputObject != null && inputObject.Type != JTokenType.Null)
{
JToken bodyValue = inputObject;
if (bodyValue != null && bodyValue.Type != JTokenType.Null)
{
this.Body = ((string)bodyValue);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{ED5A1926-ED9F-47A3-8E07-79F046761F2A}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HelloWorld</RootNamespace>
<AssemblyName>HelloWorld</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Rest.ClientRuntime">
<HintPath>packages\Microsoft.Rest.ClientRuntime.0.9.0\lib\net45\Microsoft.Rest.ClientRuntime.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Generated\*.cs" />
<Compile Include="Generated\Models\*.cs" />
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,21 @@
using System;
using System.Net;
using AutoRest01;
namespace SampleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new Client01().GetGreeting().Body);
var client01 = new Client01();
var result = client01.GetGreeting();
var salutation = result.Body;
Console.WriteLine(salutation);
Console.WriteLine("Enter to exit.");
Console.ReadLine();
}
}
}

Просмотреть файл

@ -0,0 +1,89 @@
# Swagger HelloWorld #
Swagger is written in JSON. The spec must conform to the [Swagger schema](https://raw.githubusercontent.com/swagger-api/swagger-spec/master/schemas/v2.0/schema.json).
Let's put together a minimal spec to document the service.
Every Swagger spec starts with a field declaring the version of Swagger being used. AutoRest supports version 2.0.
```
{
"swagger": "2.0"
```
The `info` object is required. The two required fields are title and version.
AutoRest uses the title as the class name of the generated client library.
```
"info": {
"title": "Client01",
"version": "1.0.0"
},
```
Next, we include the name of the host. The Swagger schema doesn't require the host. If it is not provided, it is assumed that the document is being retrieved from the host that also serves the API. In the following examples, we include the host explicitly. The value can specify the hostname or ip address and a port value if needed.
```
"host": "swaggersample.azurewebsites.net",
```
The `paths` object is a collection of individual paths and details about the operations, parameters, and responses.
```
"paths": {
...
}
```
The HelloWorld operation is exposed at
```
"/api/HelloWorld": {
```
The HelloWorld API only defined one operation. It is using the GET verb.
```
"get": {
```
We also include an `operationId` . The value is used by AutoRest to name the methods generating for accessing this endpoint with this verb. The Swagger schema itself does not require `operationId` but without it, automatically provisioned names can become too long or too generic.
```
"operationId": "GetGreeting",
```
Next, we document the mime types that the operation returns. Here, we are just specifying that we expect a JSON result.
```
"produces": [
"application/json"
],
```
Swagger allows specifying different types of responses per HTTP status code. For HelloWorld, we expect a 200 ("OK") and just a string. It is required by the Swagger schema that the response definition include a description. AutoRest uses it in the generated code as comments for the method. In Visual Studio, they are visible as tooltips.
```
"responses": {
"200": {
"description": "GETs a greeting.",
"schema": {
"type": "string"
}
}
}
```
Because we haven't defined any other status codes or provided a `default` response schema, the AutoRest-generated client will throw an exception if the response it gets is not a 200 OK.
By convention, Swagger documents are exposed by web services with the name `swagger.json`. Here, we are using a naming convention to make it easier to keep track of multiple examples. The title from the `info` object is *Client01* and we put it all together in a file named *swagger01.json* that looks like this:
```
{
"swagger": "2.0",
"info": {
"title": "Client01",
"version": "1.0.0"
},
"host": "swaggersample.azurewebsites.net",
"paths": {
"/api/HelloWorld": {
"get": {
"operationId": "GetGreeting",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "GETs a greeting.",
"schema": {
"type": "string"
}
}
}
}
}
}
}
```

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Rest.Common" version="0.9.0" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
</packages>

Просмотреть файл

@ -0,0 +1,26 @@
{
"swagger": "2.0",
"info": {
"title": "Client01",
"version": "1.0.0"
},
"host": "swaggersample.azurewebsites.net",
"paths": {
"/api/HelloWorld": {
"get": {
"operationId": "GetGreeting",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "GETs a greeting.",
"schema": {
"type": "string"
}
}
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,204 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using AutoRest02;
using AutoRest02.Models;
using Microsoft.Rest;
using Newtonsoft.Json.Linq;
namespace AutoRest02
{
public partial class Client02 : ServiceClient<Client02>, IClient02
{
private Uri _baseUri;
/// <summary>
/// The base URI of the service.
/// </summary>
public Uri BaseUri
{
get { return this._baseUri; }
set { this._baseUri = value; }
}
/// <summary>
/// Initializes a new instance of the Client02 class.
/// </summary>
public Client02()
: base()
{
this._baseUri = new Uri("http://swaggersample.azurewebsites.net/api");
}
/// <summary>
/// Initializes a new instance of the Client02 class.
/// </summary>
/// <param name='handlers'>
/// Optional. The set of delegating handlers to insert in the http
/// client pipeline.
/// </param>
public Client02(params DelegatingHandler[] handlers)
: base(handlers)
{
this._baseUri = new Uri("http://swaggersample.azurewebsites.net/api");
}
/// <summary>
/// Initializes a new instance of the Client02 class.
/// </summary>
/// <param name='rootHandler'>
/// Optional. The http client handler used to handle http transport.
/// </param>
/// <param name='handlers'>
/// Optional. The set of delegating handlers to insert in the http
/// client pipeline.
/// </param>
public Client02(HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
: base(rootHandler, handlers)
{
this._baseUri = new Uri("http://swaggersample.azurewebsites.net/api");
}
/// <summary>
/// Initializes a new instance of the Client02 class.
/// </summary>
/// <param name='baseUri'>
/// Optional. The base URI of the service.
/// </param>
/// <param name='handlers'>
/// Optional. The set of delegating handlers to insert in the http
/// client pipeline.
/// </param>
public Client02(Uri baseUri, params DelegatingHandler[] handlers)
: this(handlers)
{
if (baseUri == null)
{
throw new ArgumentNullException("baseUri");
}
this._baseUri = baseUri;
}
/// <param name='cancellationToken'>
/// Cancellation token.
/// </param>
public async Task<GreetingResult> GetGreetingAsync(CancellationToken cancellationToken)
{
// Tracing
bool shouldTrace = ServiceClientTracing.IsEnabled;
string invocationId = null;
if (shouldTrace)
{
invocationId = ServiceClientTracing.NextInvocationId.ToString();
Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
ServiceClientTracing.Enter(invocationId, this, "GetGreetingAsync", tracingParameters);
}
// Construct URL
string url = "";
url = url + "/greetings";
string baseUrl = this.BaseUri.AbsoluteUri;
// Trim '/' character from the end of baseUrl and beginning of url.
if (baseUrl[baseUrl.Length - 1] == '/')
{
baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
}
if (url[0] == '/')
{
url = url.Substring(1);
}
url = baseUrl + "/" + url;
url = url.Replace(" ", "%20");
// Create HTTP transport objects
HttpRequestMessage httpRequest = null;
try
{
httpRequest = new HttpRequestMessage();
httpRequest.Method = HttpMethod.Get;
httpRequest.RequestUri = new Uri(url);
// Set Headers
// Send Request
HttpResponseMessage httpResponse = null;
try
{
if (shouldTrace)
{
ServiceClientTracing.SendRequest(invocationId, httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
httpResponse = await this.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
if (shouldTrace)
{
ServiceClientTracing.ReceiveResponse(invocationId, httpResponse);
}
HttpStatusCode statusCode = httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
if (statusCode != HttpStatusCode.OK)
{
HttpOperationException ex = HttpOperationException.Create(httpRequest, null, httpResponse, responseContent);
if (shouldTrace)
{
ServiceClientTracing.Error(invocationId, ex);
}
throw ex;
}
// Create Result
GreetingResult result = new GreetingResult();
// Deserialize Response
if (statusCode == HttpStatusCode.OK)
{
result = new GreetingResult();
JToken responseDoc = null;
if (string.IsNullOrEmpty(responseContent) == false)
{
responseDoc = JToken.Parse(responseContent);
}
if (responseDoc != null)
{
result.DeserializeJson(responseDoc);
}
}
result.StatusCode = statusCode;
if (shouldTrace)
{
ServiceClientTracing.Exit(invocationId, result);
}
return result;
}
finally
{
if (httpResponse != null)
{
httpResponse.Dispose();
}
}
}
finally
{
if (httpRequest != null)
{
httpRequest.Dispose();
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AutoRest02;
using AutoRest02.Models;
namespace AutoRest02
{
public static partial class Client02Extensions
{
/// <param name='operations'>
/// Reference to the AutoRest02.IClient02.
/// </param>
public static GreetingResult GetGreeting(this IClient02 operations)
{
return Task.Factory.StartNew((object s) =>
{
return ((IClient02)s).GetGreetingAsync();
}
, operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
}
/// <param name='operations'>
/// Reference to the AutoRest02.IClient02.
/// </param>
public static Task<GreetingResult> GetGreetingAsync(this IClient02 operations)
{
return operations.GetGreetingAsync(CancellationToken.None);
}
}
}

Просмотреть файл

@ -0,0 +1,31 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AutoRest02.Models;
namespace AutoRest02
{
public partial interface IClient02 : IDisposable
{
/// <summary>
/// The base URI of the service.
/// </summary>
Uri BaseUri
{
get; set;
}
/// <param name='cancellationToken'>
/// Cancellation token.
/// </param>
Task<GreetingResult> GetGreetingAsync(CancellationToken cancellationToken);
}
}

Просмотреть файл

@ -0,0 +1,49 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace AutoRest02.Models
{
public partial class Greeting
{
private string _salutation;
/// <summary>
/// Optional.
/// </summary>
public string Salutation
{
get { return this._salutation; }
set { this._salutation = value; }
}
/// <summary>
/// Initializes a new instance of the Greeting class.
/// </summary>
public Greeting()
{
}
/// <summary>
/// Deserialize the object
/// </summary>
public virtual void DeserializeJson(JToken inputObject)
{
if (inputObject != null && inputObject.Type != JTokenType.Null)
{
JToken salutationValue = inputObject["Salutation"];
if (salutationValue != null && salutationValue.Type != JTokenType.Null)
{
this.Salutation = ((string)salutationValue);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
// Warning: This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Microsoft (R) AutoRest Code Generator 1.0.5529.18494
using System;
using System.Linq;
using AutoRest02.Models;
using Microsoft.Rest;
using Newtonsoft.Json.Linq;
namespace AutoRest02.Models
{
public partial class GreetingResult : HttpOperationResponse
{
private Greeting _body;
/// <summary>
/// Optional.
/// </summary>
public Greeting Body
{
get { return this._body; }
set { this._body = value; }
}
/// <summary>
/// Initializes a new instance of the GreetingResult class.
/// </summary>
public GreetingResult()
{
}
/// <summary>
/// Deserialize the object
/// </summary>
public override void DeserializeJson(JToken inputObject)
{
base.DeserializeJson(inputObject);
if (inputObject != null && inputObject.Type != JTokenType.Null)
{
JToken bodyValue = inputObject;
if (bodyValue != null && bodyValue.Type != JTokenType.Null)
{
Greeting greeting = new Greeting();
greeting.DeserializeJson(bodyValue);
this.Body = greeting;
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6EA714D8-460C-470A-9636-C6EB804DAA1D}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HelloWorldWithModel</RootNamespace>
<AssemblyName>HelloWorldWithModel</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Rest.ClientRuntime">
<HintPath>packages\Microsoft.Rest.ClientRuntime.0.9.0\lib\net45\Microsoft.Rest.ClientRuntime.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Generated\*.cs" />
<Compile Include="Generated\Models\*.cs" />
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,26 @@
using System;
using System.Net;
using AutoRest02;
namespace SampleApp
{
class Program
{
static void Main(string[] args)
{
var client02 = new Client02();
try
{
client02.GetGreeting();
}
catch (HttpOperationException e)
{
Console.WriteLine("inappropriate greeting");
Console.WriteLine(e.Message);
}
Console.WriteLine("Enter to exit.");
Console.ReadLine();
}
}
}

Просмотреть файл

@ -0,0 +1,70 @@
# RESTful API Greeting #
First, lets define a `Greeting` object that the REST API will return. It could just be a string, but in practice, API definitions revolve around the data types being handled. The `Greeting` object is a POCO model, meaning that we just care about the data it uses, not any operations on it. It has just one property, the `Salutation` string.
```
public class Greeting {
public string Salutation { get; set; }
}
```
Next, we define the REST API that returns an instance of the `Greeting` object. It is created with a route definition of /api/Greetings using the HTTP Verb `GET`.
```
public class GreetingsController : ApiController {
// GET: api/Greetings
public Greeting Get() {
Greeting result = new Greeting();
result.Salutation = "Hello Swagger World.";
return result;
}
}
```
When the `Greeting` is serialized as JSON, it looks like this:
```
{
"Salutation": "Hello Swagger World."
}
```
Next, let's look again at how the `Greeting` model object is represented in Swagger.
```
{
"swagger": "2.0",
"info": {
"title": "HelloSwagger",
"version": "1.0.0"
},
"host": "swaggersample.azurewebsites.net",
"basePath": "/api",
"paths": {
"/greetings": {
"get": {
"operationId": "GetGreeting",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "A greeting.",
"schema": {
"$ref": "#/definitions/Greeting"
}
}
}
}
}
},
"definitions": {
"Greeting": {
"properties": {
"Salutation": {
"type": "string"
}
}
}
}
}
```
The `basePath` is also not required but as the usage is common. The `basePath` is appended to the `host` in forming the URL for every request.
```
"basePath": "/api",
```

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Rest.ClientRuntime" version="0.9.0" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
</packages>

Просмотреть файл

@ -0,0 +1,36 @@
{
"swagger": "2.0",
"info": {
"title": "Client02",
"version": "1.0.0"
},
"host": "swaggersample.azurewebsites.net",
"basePath": "/api",
"paths": {
"/greetings": {
"get": {
"operationId": "GetGreeting",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "A greeting.",
"schema": {
"$ref": "#/definitions/Greeting"
}
}
}
}
}
},
"definitions": {
"Greeting": {
"properties": {
"Salutation": {
"type": "string"
}
}
}
}
}

28
Samples/Samples.sln Normal file
Просмотреть файл

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "01-HelloWorld\HelloWorld.csproj", "{ED5A1926-ED9F-47A3-8E07-79F046761F2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorldWithModel", "02-HelloWorldWithModel\HelloWorldWithModel.csproj", "{6EA714D8-460C-470A-9636-C6EB804DAA1D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ED5A1926-ED9F-47A3-8E07-79F046761F2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED5A1926-ED9F-47A3-8E07-79F046761F2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED5A1926-ED9F-47A3-8E07-79F046761F2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED5A1926-ED9F-47A3-8E07-79F046761F2A}.Release|Any CPU.Build.0 = Release|Any CPU
{6EA714D8-460C-470A-9636-C6EB804DAA1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6EA714D8-460C-470A-9636-C6EB804DAA1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EA714D8-460C-470A-9636-C6EB804DAA1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EA714D8-460C-470A-9636-C6EB804DAA1D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal