using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using pdrake.Models;
namespace pdrake.Controllers
{
public class MovieApiController : Controller
{
private const string baseUrl = "https://api.themoviedb.org/3/discover/movie?api_key=my_key";
public List<Movie> Movies { get; set; }
public async Task<AcceptedResult> GetMovies()
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(baseUrl);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
Movies = JsonConvert.DeserializeObject<List<Movie>>(Json(baseUrl));
return View(Movies);
}
}
}
I've been struggling all day trying to figure out how to transfer the Json from baseUrl to the list Movies which can be looped through with a foreach loop.
Change your using block to the following,
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(baseUrl);
string data = await response.Content.ReadAsStringAsync();
return View(JsonConvert.DeserializeObject<List<Movie>>(data));
}
This will call the baseUrl along with receiving the text / content from the response. once you have the data, you can deserialize that to your List<Movie> object and return it as a View.
Related
I am currently stuck with reading form data. Below is my controller code.
using System.Net;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using Rehub.Models;
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;
namespace Rehub_v1._0.Areas.Admin.Controllers
{
public class TestController : Controller
{
private IHostingEnvironment Environment;
public TestController()
{
}
[HttpPost]
public async Task<HttpResponseMessage> Post()
{
string path = Path.Combine(this.Environment.WebRootPath, "~/App_Data");
var provider = new MultipartFormDataStreamProvider(path);
await Request.Content.ReadAsMultipartAsync(provider);
var email = new SendGridEmail
{
Dkim = provider.FormData.GetValues("dkim").FirstOrDefault(),
To = provider.FormData.GetValues("to").FirstOrDefault(),
Html = provider.FormData.GetValues("html").FirstOrDefault(),
From = provider.FormData.GetValues("from").FirstOrDefault(),
Text = provider.FormData.GetValues("text").FirstOrDefault(),
SenderIp = provider.FormData.GetValues("sender_ip").FirstOrDefault(),
Envelope = provider.FormData.GetValues("envelope").FirstOrDefault(),
Attachments = int.Parse(provider.FormData.GetValues("attachments").FirstOrDefault()),
Subject = provider.FormData.GetValues("subject").FirstOrDefault(),
Charsets = provider.FormData.GetValues("charsets").FirstOrDefault(),
Spf = provider.FormData.GetValues("spf").FirstOrDefault()
};
// The email is now stored in the email variable
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
}
I get the error on await Request.Content.ReadAsMultipartAsync(provider):
"CS1061 C# ‘HttpRequest’ does not contain a definition for ‘Content’ and no accessible extension method ‘Content’ accepting a first argument of type ‘HttpRequest’ could be found"
I'm working on an application to make api get, post, delete, update requests on c # windowsforms.
My problem is: I want to send a parameter in "Body" when requesting a get. How can I do that ?
using System.Net.Http;
using System;
using System.Threading.Tasks;
using HastaTakip.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text;
namespace HastaTakip.Api
{
public class CustomersRepository
{
public HttpClient _client;
public HttpResponseMessage _response;
public HttpRequestMessage _requestMessage;
public CustomersRepository()
{
_client = new HttpClient();
_client.BaseAddress = new Uri("http://localhost:3000/");
_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZ0aG1seW16QGhvdG1haWwuY29tIiwidXNlcklkIjoxLCJpYXQiOjE2MTM5MDY5NDMsImV4cCI6MTYxNDA3OTc0M30.NER1RMTYx41OsF26pjiMXY-pLZTE-pIg4Q73ehwGIhA");
_client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<CustomersModel> GetList()
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("business_code", "dental")
});
_response = await _client.GetAsync(content);
var json = await _response.Content.ReadAsStringAsync();
var listCS = CustomersModel.FromJson(json);
return listCS;
}
}
}
to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
But HTTP GET with a body is a somewhat unconventional construct that falls in a gray area of the HTTP specification!
You better create a class for your content data:
public class RequestData
{
pubic string BusinessCode {get; set;}
{
After this you can create your content object
public async Task<CustomersModel> GetList()
{
var data=new RequestData{BusinessCode="dental"}
var stringData = JsonConvert.SerializeObject(data);
contentData = new StringContent(stringData, Encoding.UTF8, "application/json");
var response = await _client.GetAsync(contentData);
// but I am not sure that Get will work correctly so I recommend to use
var response = await _client.PostAsync(contentData);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<CustomersModel>(stringData);
}
else
{
....error code
}
}
I'm new to .NET and I'm making a web api with asp.net. I'm trying to post a file to AWS S3 using the AWS .Net SDK.
It works but not if I try to read the fileName and send that as the key. It only works if I hardcode the key to a string (whereas I always want the key to be the same as the filename of the uploaded file).
When I try to read the filename from the file the error I'm getting is "Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed."
So far I'm just using Postman to POST the files. I set the "Content-Type" header to multipart/form-data but exactly the same thing happens if I set it to application/x-www-form-urlencoded.
This is my UploadController:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using BlogApi.Models;
using System.Web;
using awsTestUpload;
using Amazon.S3.Model;
using Microsoft.AspNetCore.Http;
namespace BlogApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class S3UploadController : ControllerBase
{
public S3UploadController()
{
}
[HttpGet]
public ListObjectsResponse GetAll()
{
var uploader = new AmazonUploader();
return uploader.ListingObjectsAsync().Result;
}
[HttpPost]
public PutObjectResponse MyFileUpload()
{
var request = HttpContext.Request;
var fileStream = request.Body;
var contentLength = request.ContentLength;
string filePath = request.Form.Files.First().FileName;
var length = contentLength.HasValue ? (long)contentLength : 0;
var uploader = new AmazonUploader();
return uploader.sendMyFileToS3(fileStream, filePath, length).Result;
}
}
}
and the Uploader class looks like this:
using System;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using System.IO;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Microsoft.Extensions.Configuration;
namespace awsTestUpload
{
public class AmazonUploader
{
public AmazonUploader() {
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
client = new AmazonS3Client(Configuration["aws:AWS_KEY"],
Configuration["aws:AWS_SECRET"], bucketRegion);
}
private IAmazonS3 client;
public static IConfiguration Configuration { get; set; }
private const string bucketName = "my-bucket-name";
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.EUWest2;
public async Task<ListObjectsResponse> ListingObjectsAsync()
{
ListObjectsRequest request = new ListObjectsRequest
{
BucketName = bucketName
};
return await client.ListObjectsAsync(request);
}
public async Task<PutObjectResponse> sendMyFileToS3(System.IO.Stream inputStream, string fileNameInS3, long contentLength = 0)
{
PutObjectRequest request = new PutObjectRequest
{
BucketName = bucketName,
Key = fileNameInS3,
InputStream = inputStream
};
request.Headers.ContentLength = contentLength;
return await client.PutObjectAsync(request);
}
}
}
When I debug and set a breakpoint, the value of filePath is a string matching the file name ( as I expect) but the upload is timing out. if I just set filePath to be a hardcoded string (ie replace string filePath = request.Form.Files.First().FileName; with string filePath = "foo.png";) it works fine.
Can anyone see why there's a difference?
I have a Middleware that logs the request information in my ASP.Net core API project, but the proble is when I read the request in the middleware, I can't read the same request in my Controller.
Who can I read the Json request in my Middleware and in my Controller?
Middleware Comtroller
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using srpago_oxxo.Library.Logger;
using srpago_oxxo.Library.Logger.Handlers;
using srpago_oxxo.Library.Logger.Formatters;
using Microsoft.AspNetCore.Http.Internal;
namespace srpago_oxxo.Middlewares
{
public class IOMiddleware
{
private readonly RequestDelegate _next;
private Logger logger;
public IOMiddleware(RequestDelegate next)
{
_next = next;
logger = new Logger("SRPAGO-OXXO");
var formatter = new WebFormatter();
var handler = new StdoutHandler();
handler.SetFormatter(formatter);
logger.AddHandler(handler);
}
public async Task Invoke(HttpContext context)
{
var contentLenth = context.Request.ContentLength.ToString();
contentLenth = contentLenth == "" ? "-" : contentLenth;
var info = new Dictionary<string, string>()
{
{"{code}", "200"},
{"{clientIp}", context.User.ToString()},
{"{method}", context.Request.Method},
{"{path}", context.Request.Path.Value},
{"{bodyLength}", contentLenth},
{"{message}", await GetJsonRequest(context)},
};
logger.Info(info);
await _next.Invoke(context);
}
private async Task<string> GetJsonRequest(HttpContext context)
{
var body = context.Request.Body;
context.Request.EnableRewind();
var request = context.Request;
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
var bodyAsText = Encoding.UTF8.GetString(buffer);
request.Body = body;
if (bodyAsText == "")
{
bodyAsText = "{}";
}
return bodyAsText;
}
}
}
This is my Base Controller
using System.IO;
using Microsoft.AspNetCore.Mvc;
namespace srpago_oxxo.Controllers
{
public class BaseController : Controller
{
protected string GetJsonRequest()
{
var request = this.HttpContext.Request;
var stream = new StreamReader(request.Body);
var body = stream.ReadToEnd()
.Replace("\n", "")
.Replace("\t", "");
return body;
}
}
}
When I use the function GetJsonRequest after the IOMiddleware logs the request data, it does'nt return any data at all.
Can you help me whit this problem?
I'm pretty new to rest API and restsharp so I need some help. I need to get a magento version 2.2.3 admin token but I keep getting a bad request. I've followed this tutorial: https://www.youtube.com/watch?v=2sdGuC7IUAI&t=343s. But I'm ending up with a bad request. When I check the statuscode using a the breakpoints from the tutorial I get: NotFound.
My main goal is to get the categories I have in Magento. But to get that I need an admin token. I already have a bearer acces code etc.
I would really appreciate your help.
my code so far:
magento.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RestSharp;
using Newtonsoft.Json;
namespace MagentoTest
{
public class magento
{
private RestClient Client { get; set; }
private string Token { get; set; }
public magento(string magentoUrl)
{
Client = new RestClient(magentoUrl);
}
public magento(string magentoUrl,string token)
{
Client = new RestClient(magentoUrl);
Token = token;
}
public string GetAdminToken(string userName, string passWord)
{
var request = CreateRequest("/rest/V1/integration/admin/token", Method.POST);
var user = new Credentials();
user.username = userName;
user.password = passWord;
string Json = JsonConvert.SerializeObject(user, Formatting.Indented);
request.AddParameter("aplication/json", Json, ParameterType.RequestBody);
var response = Client.Execute(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
return response.Content;
}
else
{
return "";
}
}
private RestRequest CreateRequest(string endPoint, Method method)
{
var request = new RestRequest(endPoint, method);
request.RequestFormat = DataFormat.Json;
return request;
}
}
}
Credentials:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MagentoTest
{
public class Credentials
{
public string username { get; set; }
public string password { get; set; }
}
}
(Client)
Program.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MagentoTest;
namespace Client
{
class Program
{
static void Main(string[] args)
{
GetToken("blabla", "blabla");
}
static void GetToken(string userName, string passWord)
{
var m2 = new magento("http://beta.topprice24.com");
string token = m2.GetAdminToken(userName, passWord);
}
}
}
It looks, relative URL needs to be changed as "/rest/default/V1/integration/admin/token"
(https://devdocs.magento.com/guides/v2.1/get-started/order-tutorial/order-admin-token.html).
I have simplified the above code and you can easily get the token.
Keep your Credentials class as it is and change your main program as below
Modified Code:(Program.cs)
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client
{
class Program
{
static void Main(string[] args)
{
//Base URL needs to be Specified
String host = "http://beta.topprice24.com";
//Relative URL needs to be Specified
String endpoint = "/rest/default/V1/integration/admin/token";
RestClient _restClient = new RestClient(host);
var request = new RestRequest(endpoint, Method.POST);
//Initialize Credentials Property
var userRequest = new Credentials{username="blabla",password="blabla"};
var inputJson = JsonConvert.SerializeObject(userRequest);
//Request Header
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
//Request Body
request.AddParameter("application/json", inputJson, ParameterType.RequestBody);
var response = _restClient.Execute(request);
var token=response.Content;
}
}
}