https://github.com/sulmar/santander.webapi
Przykłady ze szkolenia WebApi 2
https://github.com/sulmar/santander.webapi
signalr webapi-2
Last synced: 12 months ago
JSON representation
Przykłady ze szkolenia WebApi 2
- Host: GitHub
- URL: https://github.com/sulmar/santander.webapi
- Owner: sulmar
- Created: 2019-09-18T14:03:53.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-07T23:01:30.000Z (about 3 years ago)
- Last Synced: 2025-01-02T03:33:36.070Z (about 1 year ago)
- Topics: signalr, webapi-2
- Language: JavaScript
- Size: 230 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ASP.NET WebAPI 2
## Protokól HTTP
Zapytanie:
~~~
GET /docs/index.html HTTP/1.1
Host: www.mydomain.com
(blank line)
~~~
Odpowiedź:
~~~
HTTP/1.1 200 OK
Content-Type: text/html
Hello World!
~~~
### cURL
- Zapytanie
~~~ bash
curl -v http://localhost:51666/api/customers"
~~~
~~~ bash
curl -v http://localhost:51666/api/customers -H "Accept:application/xml"
~~~
- Wyświetlenie szczegółowych informacji
~~~ bash
curl -v --request GET http://localhost:51666/api/customers -H "Accept:application/json"
~~~
### POST
~~~ bash
curl -d "{\"id\":9,\"name\":\"asp.net core book\"}" -H "Content-Type: application/json" http://localhost:51666/api/products
~~~
## REST API
| Akcja | Opis |
|--------|-----------------------|
| GET | Pobierz |
| POST | Utwórz |
| PUT | Zamień |
| DELETE | Usuń |
| PATCH | Zmodyfikuj częściowo |
| HEAD | Czy istnieje |
## Uruchomienie usługi na kilku portach
~~~ csharp
static void Main()
{
StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:5000");
options.Urls.Add("http://localhost:5010/");
// Start OWIN host
using (WebApp.Start(options))
{
Console.ReadLine();
}
}
~~~
## Kontroler
### Ustawienie trasy
~~~ csharp
[RoutePrefix("api/zamowienia")]
public class OrdersController : ApiController
{
}
~~~
## Akcje
### Reguły
~~~ csharp
public class OrdersController : ApiController
{
[Route()]
public string Get()
{
Console.WriteLine(this.Request);
return "Hello Web Api";
}
[Route("{id}")]
public string Get(string id)
{
return $"Hello string {id}";
}
[Route("{id:int}")]
public string Get(int id)
{
return $"Hello Number {id}";
}
//[Route(@"{id:range(1,3)}")]
//public IHttpActionResult GetByNumber(string id)
//{
// return Ok($"Hello Range {id}");
//}
[Route(@"{id:regex(^ABC\d+$)}")]
public IHttpActionResult GetRegex(string id)
{
return Ok($"Hello Regex {id}");
}
[Route("{orderdate:DateTime}")]
public string Get(DateTime orderdate)
{
return $"Hello {orderdate.ToShortDateString()}";
}
[HttpGet]
[Route("{code:regex(^C[0-9]{3}$)}")]
public IHttpActionResult Get(string code)
{
var customer = customersService.Get(code);
if (customer == null)
{
return NotFound();
}
return Ok(customer);
}
~~~
### Własne reguły
- Definicja
~~~ csharp
public class NonZeroConstraint : IHttpRouteConstraint
{
public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
IDictionary values, HttpRouteDirection routeDirection)
{
object value;
if (values.TryGetValue(parameterName, out value) && value != null)
{
long longValue;
if (value is long)
{
longValue = (long)value;
return longValue != 0;
}
string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
if (Int64.TryParse(valueString, NumberStyles.Integer,
CultureInfo.InvariantCulture, out longValue))
{
return longValue != 0;
}
}
return false;
}
}
~~~
- Rejestracja
~~~ csharp
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));
config.MapHttpAttributeRoutes(constraintResolver);
}
}
~~~
- Użycie
~~~ csharp
[Route("{id:nonzero}")]
public HttpResponseMessage GetNonZero(int id) { ... }
~~~
### Złożone obiekty jako parametry
~~~ csharp
public class GeoPoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public ValuesController : ApiController
{
public IHttpActionResult Get([FromUri] GeoPoint location) { ... }
}
~~~
http://localhost/api/values/?Latitude=52.678558&Longitude=28.130989
~~~ csharp
public IHttpActionResult Get([FromUri] OrderSearchCriteria criteria)
{
var orders = OrderRepository.Get(criteria);
return Ok(loads);
}
~~~
### GET
~~~ csharp
public IHttpActionResult Get(int id)
{
var customer = CustomerRepository.Get(id);
if (customer == null)
{
return NotFound();
}
return Ok(customer);
}
~~~
~~~ csharp
[Route("api/customers/{customerId}/orders")]
public async Task GetByCustomer(int customerId)
{
var orders = await CustomerRepository.GetAsync(customerId);
return Ok(orders);
}
~~~
### HEAD
### Mieszane
~~~ csharp
[AcceptVerbs("GET", "HEAD")]
public IHttpActionResult Get(int id)
{
var customer = CustomerRepository.Get(id);
if (customer == null)
{
return NotFound();
}
if (this.Request.Method == HttpMethod.Head)
{
return Ok();
}
else
{
return Ok(customer);
}
}
~~~
### POST
~~~ csharp
public async Task Post(Customer customer)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
await CustomerRepository.AddAsync(customer);
// return Created($"http://localhost:9000/api/customers/{customer.Id}", customer);
return CreatedAtRoute("DefaultApi", new { id = customer.Id }, customer);
}
~~~
### PUT
~~~ csharp
[Route("{id}")]
public async Task Put(int id, [FromBody] Customer customer)
{
if (id != customer.Id)
{
return BadRequest();
}
await CustomerRepository.UpdateAsync(customer);
return Ok();
}
~~~
### DELETE
~~~ csharp
public IHttpActionResult Delete(int id)
{
CustomerRepository.Remove(id);
return Ok();
}
~~~
## Generyczny kontroler
~~~ csharp
public abstract class BaseController : ApiController
where TEntity : BaseEntity
{
protected readonly IEntityRepository entityRepository;
public BaseController(IEntityRepository entityRepository)
{
this.entityRepository = entityRepository;
}
public virtual async Task Get()
{
var entities = await entityRepository.GetAsync();
return Ok(entities);
}
public virtual async Task Get(TKey id)
{
TEntity entity = await entityRepository.GetAsync(id);
if (entity == null)
return NotFound();
return Ok();
}
[Route("api/{controller}/{id}")]
public virtual async Task Put(TKey id, TEntity entity)
{
await entityRepository.UpdateAsync(entity);
return Ok();
}
public virtual async Task Post(TEntity entity)
{
await entityRepository.AddAsync(entity);
return CreatedAtRoute("DefaultApi", new { id = entity.Id }, entity);
}
public virtual async Task Delete(int id)
{
await entityRepository.DeleteAsync(id);
return Ok();
}
}
~~~
## ngrok
- Wystawienie usługi hostowanej w IIS Express:
~~~ bash
ngrok http -host-header="localhost:[port]" [port]
~~~
## Usługa jako Windows Service
Instalacja
~~~ powershell
Install-Package TopShelf
~~~
Instalacja usługi wraz z uruchomieniem
~~~ bash
ApiService install start
~~~
Odinstalowanie usługi
~~~ bash
ApiService uninstall
~~~
## Pobranie strumienia danych
~~~ csharp
public class StreamActionResult : IHttpActionResult
{
private readonly Stream Stream;
public StreamActionResult(Stream stream)
{
this.Stream = stream;
}
public Task ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StreamContent(Stream);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
return Task.FromResult(response);
}
}
~~~
### Przykład użycia Crystal Reports
~~~ csharp
public class ReportsController : ApiController
{
public IHttpActionResult Get()
{
var reports = Directory.GetFiles(@"Reports\", "*.rpt")
.Select(f => Path.GetFileNameWithoutExtension(f));
return Ok(reports);
}
public IHttpActionResult Get(string id)
{
var parameters = this.Request.GetQueryNameValuePairs();
string filename = $@"Reports\{id}.rpt";
if (!File.Exists(filename))
{
return NotFound();
}
var rpt = new ReportDocument();
rpt.Load(filename);
foreach (var parameter in parameters)
{
rpt.SetParameterValue(parameter.Key, parameter.Value);
}
var stream = rpt.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
return new StreamActionResult(stream);
}
}
~~~
## Upload pliku
~~~ csharp
public class FilesController : ApiController
{
public async Task Post()
{
var provider = new MultipartMemoryStreamProvider();
await this.Request.Content.ReadAsMultipartAsync(provider);
foreach (var file in provider.Contents)
{
var filename = file.Headers.ContentDisposition.FileName;
var buffer = await file.ReadAsByteArrayAsync();
File.WriteAllBytes(filename, buffer);
}
return Ok();
}
}
~~~
## Filtry
### Filtr akcji
Czas wykonania
~~~ csharp
public class ExecutionTimeFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
actionContext.Request.Properties[actionContext.ActionDescriptor.ActionName] = Stopwatch.StartNew();
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
var stopwatch = (Stopwatch) actionExecutedContext.Request.Properties[actionExecutedContext.ActionContext.ActionDescriptor.ActionName];
var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
Trace.WriteLine($"{actionName} - elapsed - {stopwatch.Elapsed}");
}
}
~~~
Rejestracja filtrów
~~~ csharp
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ExecutionTimeFilterAttribute());
config.Filters.Add(new ValidationModelStateAttribute());
}
}
~~~
Walidacja
~~~ csharp
public class ValidationModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
actionContext.Response =
actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
base.OnActionExecuting(actionContext);
}
}
~~~
## Wstrzykiwanie zależności
### Unity
- Instalacja biblioteki
~~~ powershell
Install-Package Unity
~~~
- Implementacja
~~~ csharp
public class UnityDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer container;
public UnityDependencyResolver(IUnityContainer container)
{
this.container = container;
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityDependencyResolver(child);
}
public void Dispose()
{
container.Dispose();
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch(ResolutionFailedException)
{
return null;
}
}
public IEnumerable GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return Enumerable.Empty();
}
}
}
~~~
- Rejestracja
~~~ csharp
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
IUnityContainer container = new UnityContainer();
container.RegisterType();
container.RegisterType();
container.RegisterInstance(new CustomerFaker());
container.RegisterInstance(new ProductFaker());
config.DependencyResolver = new UnityDependencyResolver(container);
}
}
~~~
## Problem kropki
~~~ xml
~~~