Uploading File (IfromFile) via HttpClient To webApi - asp.net

Need help. I am trying to save or uploud a file (IFormFile) from a Project Web to the Web Api, consuming the web api via httpClient. I am getting the following error: System.NotSupportedException: The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.IFormFile.Headers' is not supported.enter image description here
enter image description here

NotSupportedException: The collection type 'Microsoft.AspNetCore.Http.IHeaderDictionary' on 'Microsoft.AspNetCore.Http.IFormFile.Headers' is not supported.
It seems that you are serializing a FormFile, which cause the above issue.
I am trying to save or uploud a file (IFormFile) from a Project Web to the Web Api, consuming the web api via httpClient.
public async Task<IActionResult> Online([FromForm]CandidaturaAddModel model)
{
var formContent = new MultipartFormDataContent();
formContent.Add(new StringContent(model.Senha), "Senha");
formContent.Add(new StringContent(System.Text.Json.JsonSerializer.Serialize(model.AnoLectvo)), "AnoLectvo");
//...
//for other properties, such as Email, Genero etc
//...
formContent.Add(new StreamContent(model.Foto.OpenReadStream()), "Foto", Path.GetFileName(model.Foto.FileName));
_httpClient.BaseAddress = new Uri("https://localhost:xxxx/");
var response = await _httpClient.PostAsync("/api/xxx/CandidaturaAdd", formContent);
if (response.IsSuccessStatusCode)
{
//....
}
Test Result

Related

net core file uploading vis postman loading indefinitely

[HttpPost, DisableRequestSizeLimit]
[AllowAnonymous]
public async Task<IActionResult> UploadFile()
{
var formCollection = await Request.ReadFormAsync();
var file = formCollection.Files.First();
//TODO: Implement the logic
return Ok();
}
Above is the Backend code. I am trying to upload a file via postman but the request is not hitting the action and getting no errors and loading forever.
I am working with .NET 5
You should set the Body to form-data, in Postman
From there, set the KEY as File, and select a file for the VALUE field.

How to retrieve JSON data from HttpContent

I'm buildin a console Web API to communicate with a localhost server, hosting computer games and highscores for them. Every time I run my code, I get this charming error:
fail:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.NotSupportedException: Deserialization of types without a
parameterless constructor, a singular parameterized constructor, or a
parameterized constructor annotated with 'JsonConstructorAttribute' is
not supported. Type 'System.Net.Http.HttpContent'. Path: $ |
LineNumber: 0 | BytePositionInLine: 1.
This is the method I'm using to post to the database. Note that this method is not in the console application. It is in the ASP.NET Core MvC application opening a web browser and listening for HTTP requests (which can come from the console application).
[HttpPost]
public ActionResult CreateHighscore(HttpContent requestContent)
{
string jasonHs = requestContent.ReadAsStringAsync().Result;
HighscoreDto highscoreDto = JsonConvert.DeserializeObject<HighscoreDto>(jasonHs);
var highscore = new Highscore()
{
Player = highscoreDto.Player,
DayAchieved = highscoreDto.DayAchieved,
Score = highscoreDto.Score,
GameId = highscoreDto.GameId
};
context.Highscores.Add(highscore);
context.SaveChanges();
return NoContent();
}
I'm sending POST requests in a pure C# console application, with information gathered from user input, but the result is exactly the same when using Postman for post requests - the above NotSupportedException.
private static void AddHighscore(Highscore highscore)
{
var jasonHighscore = JsonConvert.SerializeObject(highscore);
Uri uri = new Uri($"{httpClient.BaseAddress}highscores");
HttpContent requestContent = new StringContent(jasonHighscore, Encoding.UTF8, "application/json");
var response = httpClient.PostAsync(uri, requestContent);
if (response.IsCompletedSuccessfully)
{
OutputManager.ShowMessageToUser("Highscore Created");
}
else
{
OutputManager.ShowMessageToUser("Something went wrong");
}
}
I'm new to all this HTTP requests stuff, so if you spot some glaring errors in my code, that would be appreciated. Though, the most important question is, what am I missing, and how can I read from the HttpContent object, to be able to create a Highscore object to send to the database?
It seems to be the string jasonHs... line that is the problem, since the app crashed in exactly the same way, when I commented out the rest of the ActionResult method.
Based on your code, we can find that you make a HTTP Post request with a json string data (serialized from a Highscore object) from your console client to Web API backend.
And in your action method, you create an instance of Highscore manually based on received data, so why not make your action accept a Highscore type parameter, like below. Then the model binding system would help bind data to action parameter(s) automatically.
[HttpPost]
public ActionResult CreateHighscore([FromBody]Highscore highscore)
{
//...

Consuming Web API in Xamarin.Forms

I created a Web API (Server) project in ASP.Net Core. Testing it with Postman is successful. Consuming the Web API from an ASP.Net Core Blazor (Client) project is also successful. I was able to display the JSon result in the Razor pages without problems. However, when I created a client project in Xamarin.Forms, I wasn't able to successfully get the JSon results but it gives me an "Error occurred while sending request" and an "InnerException "The text associated with this error code could not be found. The certificate authority is invalid or incorrect". The code I used to consume the API is below:
public async Task<List<Contact>> GetAllDataAsync()
{
var Contacts = new List<Contact>();
var uri = new Uri(string.Format(Constants.ContactsUrl, string.Empty));
try
{
var response = await _client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Contacts = JsonConvert.DeserializeObject<List<Contact>>(content);
}
}
catch (Exception ex)
{
Debug.WriteLine(#"\tERROR {0}", ex.Message);
}
return Contacts;
}
What else did I miss?

LiveAuthClient broken?

It seems very much that the current version of LiveAuthClient is either broken or something in my setup/configuration is. I obtained LiveSDK version 5.4.3499.620 via Package Manager Console.
I'm developing an ASP.NET application and the problem is that the LiveAuthClient-class seems to not have the necessary members/events for authentication so it's basically unusable.
Notice that InitializeAsync is misspelled aswell.
What's wrong?
UPDATE:
I obtained another version of LiveSDK which is for ASP.NET applications but now I get the exception "Could not find key with id 1" everytime I try either InitializeSessionAsync or ExchangeAuthCodeAsync.
https://github.com/liveservices/LiveSDK-for-Windows/issues/3
I don't think this is a proper way to fix the issue but I don't have other options at the moment.
I'm a little late to the party, but since I stumbled across this trying to solve what I assume is the same problem (authenticating users with Live), I'll describe how I got it working.
First, the correct NuGet package for an ASP.NET project is LiveSDKServer.
Next, getting user info is a multi-step process:
Send the user to Live so they can authorize your app to access their data (the extent of which is determined by the "scopes" you specify)
Live redirects back to you with an access code
You then request user information using the access code
This is described fairly well in the Live SDK documentation, but I'll include my very simple working example below to put it all together. Managing tokens, user data, and exceptions is up to you.
public class HomeController : Controller
{
private const string ClientId = "your client id";
private const string ClientSecret = "your client secret";
private const string RedirectUrl = "http://yourdomain.com/home/livecallback";
[HttpGet]
public ActionResult Index()
{
// This is just a page with a link to home/signin
return View();
}
[HttpGet]
public RedirectResult SignIn()
{
// Send the user over to Live so they can authorize your application.
// Specify whatever scopes you need.
var authClient = new LiveAuthClient(ClientId, ClientSecret, RedirectUrl);
var scopes = new [] { "wl.signin", "wl.basic" };
var loginUrl = authClient.GetLoginUrl(scopes);
return Redirect(loginUrl);
}
[HttpGet]
public async Task<ActionResult> LiveCallback(string code)
{
// Get an access token using the authorization code
var authClient = new LiveAuthClient(ClientId, ClientSecret, RedirectUrl);
var exchangeResult = await authClient.ExchangeAuthCodeAsync(HttpContext);
if (exchangeResult.Status == LiveConnectSessionStatus.Connected)
{
var connectClient = new LiveConnectClient(authClient.Session);
var connectResult = await connectClient.GetAsync("me");
if (connectResult != null)
{
dynamic me = connectResult.Result;
ViewBag.Username = me.name; // <-- Access user info
}
}
return View("Index");
}
}

Examine Request Headers with ServiceStack

What is the best way to inspect the Request Headers for a service endpoint?
ContactService : Service
Having read this https://github.com/ServiceStack/ServiceStack/wiki/Access-HTTP-specific-features-in-services I'm curious as to the preferred way to get to the Interface.
Thank you,
Stephen
Inside a ServiceStack Service you can access the IHttpRequest and IHttpResponse objects with:
public class ContactService : Service
{
public object Get(Contact request)
{
var headerValue = base.Request.Headers[headerKey];
//or the same thing via a more abstract (and easier to Mock):
var headerValue = base.RequestContext.GetHeader(headerKey);
}
}
The IHttpRequest is a wrapper over the underlying ASP.NET HttpRequest or HttpListenerRequest (depending if you're hosting on ASP.NET or self-hosted HttpListener). So if you're running in ASP.NET you can get the underlying ASP.NET HttpRequest with:
var aspnetRequest = (HttpRequest)base.Request.OriginalRequest;
var headerValue = aspnetRequest.Headers[headerKey];

Resources