public async Task <IActionResult> UpdateWeatherForecast(UpdateWeatherForecastRequest request) { // HACK: This try/catch should not be here. We only have to capture the ArgumentException because // the mapper is handling the validation for the three input temperature values in the WeatherForecastViewModel. // This is an example of technical debt; a quick solution in the short term to meet a deadline (say, a training // exercise that's occuring in T - 5 hours...), but one that needs to be tracked. The correct solution here would // be to write a custom model binder for the WeatherForecastViewModel object where it can validate that the three // input temperatures match and fail to bind if they don't. WeatherForecast newForecast; try { newForecast = _mapper.Map <WeatherForecastViewModel, WeatherForecast>(request.WeatherForecast); } catch (ArgumentException e) { return(BadRequest(e.Message)); } newForecast = await _weatherForecastService.UpdateWeatherForecast(newForecast); var result = _mapper.Map <WeatherForecast, WeatherForecastViewModel>(newForecast); var response = new WeatherForecastResponse { Forecast = result }; return(Ok(response)); }
public WeatherServiceTests() { _mockWeatherEndpoint = new Mock <IWeatherEndpoint>(); _dummyWeatherResponse = new WeatherForecastResponse { ConsolidatedWeather = new List <Weather> { new Weather { WeatherStateName = "Dummy WeatherStateName", ApplicableDate = "2020-05-30", WeatherStateAbbr = "Dummy WeatherStateAbbr" } } }; _dummyAreaInformation = new AreaInformation { Title = "Dummy Title", Woeid = 1, LattLong = "Dummy LattLong", LocationType = "Dummy LocationType" }; }
public async Task <IActionResult> Get([FromQuery] int locationId, [FromQuery] DateTime date) { // Thanks to the Range attribute on the `GetWeatherForecastRequest` LocationId property, // we don't have to validate the location id here. If the range wasn't satisfied, the caller // will automatically be sent back a 400 - bad request. // Use the below format when logging to ensure the cuda logger can pick up on the individual parameters passed in during string formatting // so they can be captured and logged separately to be searchable later. _logger.LogInformation("Requesting weather forecast for location {locationId} on date {date}", locationId, date); var forecast = await _weatherForecastService.GetWeatherForecastForDate(locationId, date); // Since WeatherForecast and WeatherForecastViewModel don't have matching properties, we'll need to write a TypeConverter for AutoMapper to use // to do the mapping for us. We then need to configure AutoMapper to use our TypeConverter in WebMapperProfile.cs. var viewModel = _mapper.Map <WeatherForecast, WeatherForecastViewModel>(forecast); // It's a good practice to always return data from APIs in response 'envelopes'. Even if you're only returning a single entity, // the response envelope ensures that clients can always count on getting a single JSON object back. When designing public APIs, consistency // across endpoints is absolutely key to making an API easy and enjoyable to use. var response = new WeatherForecastResponse { Forecast = viewModel }; // Since we inherit from the framework provided `ControllerBase` class, we're given access to several static helper methods which easily create // the appropriate IActionResult concrete response object. Here, `Ok(response)` takes our response object, serializes it to json, and returns // a 200 - OK http response with our response data in the response body. All in one line. return(Ok(response)); }
private WeatherViewData CreateErrResponse(WeatherForecastResponse resp) { var viewData = new WeatherViewData(); viewData.Message = resp.Message; return(viewData); }
private WeatherViewData CreateWeatherViewData(WeatherForecastResponse resp) { var viewData = new WeatherViewData { Message = resp.Message, City = resp.City.Name, Current = new WeatherDTO() { Humidity = resp.List[0].Main.Humidity, Temperature = ConvertToCelsius(resp.List[0].Main.Temp) // Kelvin to Celsius }, DateTime = resp.List[0].Dt * 1000, NextFiveDays = new List <WeatherDTO>() }; // to ms const int dataPointsPerDay = 8; for (int i = 0; i < 5; i++) { var dailyWeatherData = resp.List.Skip(i * dataPointsPerDay).Take(dataPointsPerDay).ToList(); var humidity = dailyWeatherData.Sum(data => data.Main.Humidity) / (double)dataPointsPerDay; var temp = dailyWeatherData.Sum(data => data.Main.Temp) / (double)dataPointsPerDay; var w = new WeatherDTO { Humidity = Math.Round(humidity, 2), Temperature = ConvertToCelsius(temp) // Kelvin to Celsius }; viewData.NextFiveDays.Add(w); } return(viewData); }
public override Task <WeatherForecastResponse> GetWeatherForecast(Empty request, ServerCallContext context) { var response = new WeatherForecastResponse(); response.Forecasts.AddRange(GetWeatherForecast()); return(Task.FromResult <WeatherForecastResponse>(response)); }
private IEnumerable <WeatherForecastDto> ConvertToDailyWeatherForecastData(WeatherForecastResponse weatherForecastResponse) => weatherForecastResponse.Items .GroupBy(i => i.ForecastDateTime.Date) .Select(i => new WeatherForecastDto { Date = i.Key.Date.ToUniversalTime(), Temperature = Math.Round(i.Average(x => x.Info.Temperature), 2), Humidity = Math.Round(i.Average(x => x.Info.Humidity), 0), WindSpeed = Math.Round(i.Average(x => x.WindInfo.Speed), 2) });
private WeatherForecastResponse GetTwoDaysWeatherForecastResponse() { var result = new WeatherForecastResponse { Code = "200", Count = 6, Items = GetTwoDaysWeatherForecastInfoItems() }; return(result); }
public async Task <WeatherForcastResponseDto> Get(WeatherForcastRequestDto requestDto) { WeatherForecastResponse weatherForecastResponse = new WeatherForecastResponse(); _ = (requestDto.GetRequestValue() switch { (nameof(requestDto.City), _) => weatherForecastResponse = await _weatherForecast.GetWeatherForecastByCityNameAsync(requestDto.City, Countries.Germany), (nameof(requestDto.ZipCode), _) => weatherForecastResponse = await _weatherForecast.GetWeatherForecastByZipCodeAsync(requestDto.ZipCode, Countries.Germany), (_, _) => throw new RequestInvalidException("Input must be identified!") });
public ForecastServiceTest() { _openWeatherMapConfig = new OpenWeatherMapConfig { IconUrl = "fakeurl/{0}.png" }; _mockMapper = new Mock <IMapper>(); _mockGetForecastFunc = new Mock <Func <string, string, string, Task <WeatherForecastResponse> > >(); _mockGetCurrentWeatherFunc = new Mock <Func <string, string, string, Task <CurrentWeatherResponse> > >(); _mapper = new MapperConfiguration(cfg => { cfg.AddProfile(new WeatherForecastMappingProfile()); }).CreateMapper(); _mockCurrentWeatherResponse = new CurrentWeatherResponse() { DateUnixFormat = 1590144273, WeatherInfo = new WeatherCondition { Temperature = 69.55, Humidity = 50 }, WindData = new Wind { Speed = 9.53 }, WeatherData = new WeatherResponse[] { new WeatherResponse { Icon = "04d" } } }; _mockWeatherForecastResponse = new WeatherForecastResponse() { CityData = new City { Name = "Hamburg", Country = "DE" }, ForecastData = new ForecastResponse[] { new ForecastResponse { DateUnixFormat = 1590559200, WeatherInfo = new WeatherCondition { Temperature = 69.55, Humidity = 50 }, WindData = new Wind() { Speed = 9.53 }, WeatherData = new WeatherResponse[] { new WeatherResponse { Icon = "04d" } } } } }; }
public override Task <WeatherForecastResponse> GetForecasts(Empty request, ServerCallContext context) { var result = new WeatherForecastResponse(); var rng = new Random(); var forecasts = Enumerable.Range(1, 500).Select(index => new WeatherForecastDTO { Date = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(index)), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }).ToArray(); result.Forecasts.AddRange(forecasts); return(Task.FromResult(result)); }
public async Task <WeatherForecastResponse> GetWithServiceUnavailable() { return(await ValidateAndProcessRequestWithGuardAsync(new object(), async req => { _logger.LogInformation($"Call to {nameof(GetWithServiceUnavailable)}"); WeatherForecastResponse weatherForecastResponse = new WeatherForecastResponse() { WeatherForecast = await _weatherForecastApiService.GetWithServiceUnavailable(), ErrorCode = ResponseErrorCode.None, Message = MessageConstants.Ok, Status = true, CorrelationId = Guid.NewGuid() }; return weatherForecastResponse; })); }
public async Task <IActionResult> CreateWeatherForecast(CreateWeatherForecastRequest request) { var location = _mapper.Map <LocationViewModel, Location>(request.Location); var date = request.Date; var summary = request.Summary; var temperature = (decimal)request.Temperature; var scale = request.Scale; var result = await _weatherForecastService.CreateWeatherForecast(location, date, temperature, scale, summary); var viewModel = _mapper.Map <WeatherForecast, WeatherForecastViewModel>(result); var response = new WeatherForecastResponse { Forecast = viewModel }; return(Ok(response)); }
public IHttpActionResult GetForecast(string city) { string url = baseUrl + "forecast?units=metric&appid=" + apiKey + "&q=" + city; string responseText = GetResponseText(url); WeatherForecastResponse response = JsonConvert.DeserializeObject <WeatherForecastResponse>(responseText); // If the response is an error, then we give only the code and the error message if (response.Cod != "200") { WeatherErrorResponse errorResponse = new WeatherErrorResponse { Cod = response.Cod, Message = response.Message }; return(Json(errorResponse)); } return(Json(response)); }
public WeatherForecastResponse GetWeatherExecute(WeatherForecastRequest request) { var rng = new Random(); var listatempo = Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }).ToArray(); //ValidaLista<WeatherForecast> validaLista = new ValidaLista<WeatherForecast>(); var wheather = new WeatherForecastResponse(); wheather.Weathers = listatempo; //listaComUmItem.Add(validaLista.ObtemPrimeirItemLista<WeatherForecastResponse>(listatempo, request.Summary)); return(wheather); }
public WeatherForecastResponse GetWeatherForecastData(int zipCode, string cityName) { var apikey = Environment.GetEnvironmentVariable("OPENWEATHER_APIKEY"); var client = new HttpClient(); var queryParam = String.IsNullOrEmpty(cityName)? $"zip={zipCode}":$"q={cityName}"; var resp = client.GetAsync( $"https://api.openweathermap.org/data/2.5/forecast?{queryParam},de&appid={apikey}") .Result; if (resp.StatusCode == HttpStatusCode.OK) { return(WeatherForecastResponse.FromJson(resp.Content.ReadAsStringAsync().Result)); } var errorResponse = WeatherForecastErrorResponse.FromJson(resp.Content.ReadAsStringAsync().Result); return(new WeatherForecastResponse() { StatusCode = errorResponse.StatusCode, Message = errorResponse.Message }); }
public static WeatherForecastModel Convert(WeatherForecastResponse requestObject) { if (requestObject == null) { throw new ArgumentNullException(); } return(new WeatherForecastModel { Location = new LocationModel { City = requestObject.Location.City, Country = requestObject.Location.Country }, Tempreature = new TempreatureModel { Format = requestObject.Tempreature.Format, Value = requestObject.Tempreature.Value }, Humidity = requestObject.Humidity }); }
public async Task <IActionResult> GetById(int id) { // Because we're taking in a value type and not a request object, we have to do model validation ourselves. if (id <= 0) { return(BadRequest(new ErrorResponse { ErrorMessage = "Weather Forecast ID's must be positive integers." })); } var weatherForecast = await _weatherForecastService.GetWeatherForecastById(id); var viewModel = _mapper.Map <WeatherForecast, WeatherForecastViewModel>(weatherForecast); var response = new WeatherForecastResponse { Forecast = viewModel }; return(Ok(response)); }
public async Task <IActionResult> Index() { // Make an API GET Call to the following URL: // http://www.7timer.info/bin/api.pl?lon=-76.8867&lat=40.2731&product=civillight&output=json try { var queryStringParams = new Dictionary <string, string>() { { "lon", "-76.8867" }, { "lat", "40.2731" }, { "product", "civillight" }, { "output", "json" } }; var pathAndQuerystring = QueryHelpers.AddQueryString("/bin/api.pl", queryStringParams); var httpResponseMessage = await client.GetAsync(pathAndQuerystring); if (httpResponseMessage.IsSuccessStatusCode) { var jsonResult = await httpResponseMessage.Content.ReadAsStringAsync(); return(View(WeatherForecastResponse.FromJson(jsonResult))); } else { return(View("Error", new ErrorViewModel() { ErrorMessage = "API call failed. Please try again later." })); } } catch (Exception ex) { //TODO: log ex.Message return(View("Error", new ErrorViewModel() { ErrorMessage = "An unexpected error occurred. Please try again later." })); } }
public override Task <WeatherForecastResponse> GetWeatherForecast(WeatherForecastRequest request, ServerCallContext context) { //Get random weather for a specific region. var rng = new Random(); var value = rng.Next(-20, 55); var weatherForecast = Enumerable.Range(1, 5).Select(index => new WeatherForecastItem { CityName = request.CityName, Date = Timestamp.FromDateTime(DateTime.Now.ToUniversalTime().AddDays(index)), TemperatureC = value, TemperatureK = 32 + (int)(value / 0.5556), Summary = Summaries[rng.Next(Summaries.Length)] }).ToArray(); //Create response var result = new WeatherForecastResponse(); foreach (var weather in weatherForecast) { result.Items.Add(weather); } return(Task.FromResult(result)); }
public WeatherForecastResponse ObtenerTemperaturas() { WeatherForecastResponse resultado; try { var rng = new Random(); resultado = new WeatherForecastResponse() { WeatherForecast = Enumerable.Range(1, 5).Select(index => new WeatherForecastEntity { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(), response = new ResponseStatus { mensaje = "Transaccion realizada con exito", codigo = 200 } }; } catch (Exception ex) { resultado = new WeatherForecastResponse() { response = new ResponseStatus { mensaje = "Ocurrio un error al tratar de obtener los datos " + ex.Message, codigo = 404 } }; } return(resultado); }