Data not updating when PUT API in Xamarin - xamarin

I have 1 question here, thanks for your help I have solved the problem. Now I have the same problem thinking I did the right thing, however it is not so
Button Update
UserPage.xaml
<controls:CustomEntry x:Name="txt_name" Text="{Binding CustomerGets.NameUs}"/>
<controls:CustomEntry x:Name="txt_address" Text="{Binding CustomerGets.Address}"/>
<Button x:Name="bt_updateuser" Clicked="bt_updateuser_Clicked" VerticalOptions="Center" Text="Update">
UserPage.xaml.cs
private async void bt_updateuser_Clicked(object sender, EventArgs e)
{
....
var url = baseUrl + userget;
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", mytokenlogin);
string jsonStr = await client.GetStringAsync(url);
var res = JsonConvert.DeserializeObject<Customer>(jsonStr);
res.NameUs = txt_name.Text;
res.Address = txt_address.Text;
......
var urlput = "xxxxx/api/Customers/" + userget;
var stringContent = new StringContent(JsonConvert.SerializeObject(res), Encoding.UTF8, "application/json");
await client.PutAsync(urlput, stringContent);
}
When I debug
I see the data in the received res, so why is it not updated. I tried on Posman, swagger it works
Where did I go wrong? Please help, thanks

Related

Async Http Request from component in Blazor

Im creating a list of components in Blazor, each one of these components need to request some data from a webpage. The list are created as follows on a .razor page:
#foreach(stringcomp in Complist){
<myComponent />
}
around 100 components are created. On all of these components the following URL request is preformed (using this code):
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await GetUrl("some url here");
}
}
public async Task<string> GetUrl(string url)
{
HttpClient client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("User-Agent", "get data service");
var response = await client.SendAsync(request).ConfigureAwait(false);
string res = null;
if (response.IsSuccessStatusCode)
{
using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
var streamReader = new StreamReader(responseStream);
res = await streamReader.ReadToEndAsync().ConfigureAwait(false);
}
return res;
}
Doing this I'm running in to some problems where most of my calls to SendAsync never returns a value. I have come to understand that this is because of a lock-state but for the life of me can't figure out how to solve it. most similar answers suggest setting .ConfigureAwait(false) but this does not yeald a different result in my case.
So my question is: Hos can i request webbpages simultaneously in different components and be sure that they won't hang/lookup. As theres many requests that some times takes a long time (5-10 sec) to complete it's not an alternative to do them synchronously.
It might also be of importance to mention that me code and pages are separated, every .razor page are using #inherits to get its functions/logic
Try to use IHttpClientFactory as follows:
[Inject] public IHttpClientFactory clientFactory { get; set;}
using System.IO;
Your GetUrl method:
public async Task<string> GetUrl(string url)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("User-Agent", "get data service");
var client = clientFactory.CreateClient();
var response = await client.SendAsync(request);
string res = null;
if (response.IsSuccessStatusCode)
{
using var responseStream = await response.Content.ReadAsStreamAsync();
var streamReader = new StreamReader(responseStream);
res = await streamReader.ReadToEndAsync().ConfigureAwait(false);
}
return res;
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
// More code here...
}
Hope this works...

How to save the final photo in Forms.Image to local in xamarin forms

I'm making an app for android with Xamarin forms where the user would select a photo from their library, add a White border to make it a square, then save it. I'm stuck at the saving part, can't figure it out
I am using the normal Xamarin.Forms.Image control
<Image HorizontalOptions="CenterAndExpand"
VerticalOptions="Center"
BackgroundColor="Transparent"
Grid.Column="0"
Grid.Row="0"
x:Name="imgViewer"/>
this is how I select the photo
async void tbAdd_Activated(object sender, System.EventArgs e)
{
var file = await CrossFilePicker.Current.PickFile();
if (file != null)
{
imgViewer.Source = ImageSource.FromFile(file.FilePath);
imgViewer.BackgroundColor = Color.White;
}
}
But then I have a save button to save that final image with the border to the camera roll but I have no idea how to save it, I've searched everywhere but can't seem to find!
Anyone knows how to do that ?
You will have to specific codes in iOS and android to save the images and Also add required permissions in iOS by adding this key to info.Plist file
<key>NSPhotoLibraryAddUsageDescription</key>
<string>$(PRODUCT_NAME)</string>
Android :
MediaStore.Images.Media.InsertImage(Application.Context.ContentResolver, [YourFileName],
System.IO.Path.GetFileName([YourFileName]), string.Empty);
iOS :
var imageSource = CGImageSource.FromUrl(NSUrl.FromFilename( [YourFileName]));
UIImage.FromImage(imageSource.CreateImage(0, null), 1, imageOrientation)
.SaveToPhotosAlbum((image, error) => { // handle success & error here... });
You can check this link for more info.
You can save the image by the following code:
void save_Activated(object sender, System.EventArgs e)
{
if (file != null)
{
byte[] imageBytes;
var FileImage = new Image();
string base64;
using (var fs = new FileStream(file.FilePath, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
base64 = Convert.ToBase64String(buffer);
}
imageBytes = Convert.FromBase64String(base64);
File.WriteAllBytes(filename, imageBytes);
}
So the full code is like this:
string documentsFolder;
string filename;
FileData file;
ImageSource imageSource;
public MainPage()
{
InitializeComponent();
documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
filename = Path.Combine(documentsFolder, "myfile.jpg");
}
async void tbAdd_Activated(object sender, System.EventArgs e)
{
file = await CrossFilePicker.Current.PickFile();
if (file != null)
{
imgViewer.Source = ImageSource.FromFile(file.FilePath);
imgViewer.BackgroundColor = Color.White;
imageSource = imgViewer.Source;
}
}
void save_Activated(object sender, System.EventArgs e)
{
if (file != null)
{
byte[] imageBytes;
var FileImage = new Image();
string base64;
using (var fs = new FileStream(file.FilePath, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
base64 = Convert.ToBase64String(buffer);
}
imageBytes = Convert.FromBase64String(base64);
File.WriteAllBytes(filename, imageBytes);
}
}
And the xamal is:
<Button Text="AddImage" Clicked="tbAdd_Activated">
</Button>
<Button Text="SaveImage" Clicked="save_Activated">
</Button>
<Image HorizontalOptions="CenterAndExpand"
VerticalOptions="Center"
BackgroundColor="Transparent"
Grid.Column="0"
Grid.Row="0"
x:Name="imgViewer"/>

Loading Images from Web Api in Xamarin.Forms

I need to load a picture from a web api backend into my Xamarin.Forms app.
The picture is stored in an Azure Blob Storage.
This is my Web Api method:
[HttpGet("{id}")]
public HttpResponseMessage Get(int id)
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("ConnectionString");
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference("picturecontainer");
// Retrieve reference to a blob named "photo.jpg".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("picture");
var stream = new MemoryStream();
blockBlob.DownloadToStream(stream);
Image image = Image.FromStream(stream);
MemoryStream memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Jpeg);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(memoryStream.ToArray());
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
return result;
}
In my app I try to download the image bytes with the following code:
public App ()
{
_client = new HttpClient();
_client.MaxResponseContentBufferSize = 256000;
Button downloadImageBtn = new Button () {
Text = "Download Image",
};
var image = new Image() {
Source = ImageSource.FromUri (new Uri ("http://www.engraversnetwork.com/files/placeholder.jpg")),
Aspect = Aspect.AspectFit
};
downloadImageBtn.Clicked += async (object sender, EventArgs e) => {
var values = await handleClick (sender, e);
uploadPicButton.Text = values;
var imageBytes = await downloadPicture();
image.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes));
};
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
image,
downloadImageBtn
}
}
};
}
private async Task<byte[]> downloadPicture()
{
var uri = new Uri (string.Format (RestUrl, "5"));
//return await _client.GetByteArrayAsync (uri);
var response = await _client.GetAsync (uri);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsByteArrayAsync ();
return content;
}
throw new HttpRequestException ();
}
However when I click on the button, the placeholder image disappears.
Is there a problem when sending the image from the server or when receiving it in the app?
I'd not implement downloading Images manually.
If you want to load more images and/or allow to display a placeholder while loading, I recommend the FFImageLoading library. It offers nice functionality like downloading, caching, showing placeholder and error images and most important: down sampling the image to the target size. This is always a pain on android. Its available for native UI xamarin projects and for Xamarin.Froms.
You can bind strings that contain urls directly to the Source. The code would like like:
<ffimageloading:CachedImage
Source="http://thecatapi.com/?id=MTQ5MzcyNA">
</ffimageloading:CachedImage>
After blockblob.DownloadToStream line, try to set Position of the stream to 0. I'm not familiar with Azure API, but I think it may help.
Also ,try to use ReadAsStreamAsync instead of ReadAsByteArrayAsync in your downloadPicture function. Something like this:
var responseStream = await response.Content.ReadAsStreamAsync();
byte[] buf = new byte[512];
int bufSize;
while((bufSize = (await responseStream.ReadAsync(buf, 0, buf.Length))) > 0)
{
// store the received bytes to some buffer until the file is fully downloaded
}
Do you get all your content this way?

Windows Store app 8.1 Xaml pausing/resuming download using http classes

I'm trying to use http classes to pause/resume a download and pausing is easy by using the cancellation token , however how can i resume a download?
I have used the background downloader class and it had a lot of issues in resuming and had many other issues to handle downloads.
Here is my code:
using Windows.Web.Http;
using Windows.Web.Http.Filters;
private async void Foo(StorageFolder folder, string fileName)
{
Uri uri = new Uri("http://localhost");
var filter = new HttpBaseProtocolFilter();
filter.ServerCredential =
new Windows.Security.Credentials.PasswordCredential(uri.ToString(), "foo", "bar");
var client = new HttpClient(filter);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
request.Headers.Add("Range", "bytes=0-");
// Hook up progress handler.
Progress<HttpProgress> progressCallback = new Progress<HttpProgress>(OnSendRequestProgress);
var tokenSource = new CancellationTokenSource();
HttpResponseMessage response = await client.SendRequestAsync(request).AsTask(tokenSource.Token, progressCallback);
IInputStream inputStream = await response.Content.ReadAsInputStreamAsync();
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
// Copy from stream to stream.
IOutputStream outputStream = await file.OpenAsync(FileAccessMode.ReadWrite);
await RandomAccessStream.CopyAndCloseAsync(inputStream, outputStream);
}
private void OnSendRequestProgress(HttpProgress obj)
{
Debug.WriteLine(obj);
}

Authenticating to Trello API using RestSharp

I'm struggling a bit to figure out how to use Trello's OAuth API calls from my Windows Phone 7 app. The API isn't really documented, aside from a listing of the endpoints.
Here's what I have so far:
public void OnAuthenticateClicked(object sender, EventArgs e)
{
const string consumerKey = "mykey";
const string consumerSecret = "mysecret";
const string baseUrl = "https://trello.com/1";
var client = new RestClient(baseUrl)
{
Authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret)
};
var request = new RestRequest("OAuthGetRequestToken", Method.POST);
var response = client.ExecuteAsync(request, HandleResponse);
}
private void HandleResponse(IRestResponse restResponse)
{
var response = restResponse;
Console.Write(response.StatusCode);
}
I'm getting a 404 response, so something's not right, obviously.
Any suggestions?
Not using the ExecuteAsync seems to make it work:
RestRequest request = new RestRequest("OAuthGetRequestToken", Method.POST);
IRestResponse response = client.Execute(request);
Console.Write(response.StatusCode);
At one point "oAuth1 is not yet supported in async scenarios (SL and WP)", according to this post by John Sheehan.
I think your base url is incorrect.
Please try the following:
const string baseUrl = "https://api.trello.com/1";
Replace OAuthGetRequestToken with authorize.

Resources