Java.Net.SocketException Error: Socket closed in System.net.Http httpClient, occurs only when sending files larger than 50kbs - http

I am making a program in xamarin, which uses http requests to get data from an API made in net.core 2.0, but some requests (most of them actually) culminate in the following error:
System.AggregateException: One or more errors occurred. ---> Java.Net.SocketException: Socket closed
at Java.Interop.JniEnvironment+InstanceMethods.CallIntMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <286213b9e14c442ba8d8d94cc9dbec8e>:0
at Java.Net.HttpURLConnection.get_ResponseCode () [0x0000a] in <b781ed64f1d743e7881ac038e0fbdf85>:0
at Xamarin.Android.Net.AndroidClientHandler+<>c__DisplayClass45_0.<DoProcessRequest>b__1 () [0x00000] in <b781ed64f1d743e7881ac038e0fbdf85>:0
at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task.Execute () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
--- End of stack trace from previous location where exception was thrown ---
at Xamarin.Android.Net.AndroidClientHandler+<DoProcessRequest>d__45.MoveNext () [0x0036c] in <b781ed64f1d743e7881ac038e0fbdf85>:0
--- End of stack trace from previous location where exception was thrown ---
at Xamarin.Android.Net.AndroidClientHandler+<SendAsync>d__40.MoveNext () [0x00230] in <b781ed64f1d743e7881ac038e0fbdf85>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <25ebe1083eaf4329b5adfdd5bbb7aa57>:0
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task`1[TResult].GetResultCore (System.Boolean waitCompletionNotification) [0x0002b] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Threading.Tasks.Task`1[TResult].get_Result () [0x0000f] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at FonoApp.Services.DataService.SendImageAsync (System.String token, FonoApp.Model.Imagem imagem) [0x00059] in C:\Projetos Sorri\FonoApp\AppTeste\AppTeste\Services\DataService.cs:154
--- End of inner exception stack trace ---}
This error occurs in this code snippet:
public async Task<String> SendImage(string token, Imagem imagem)
{
string baseAddress = #"http://192.168.0.4:5000/" + VersaoApi + #"/Imagem/";
var json = JsonConvert.SerializeObject(imagem);
var contentString = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
try
{
HttpResponseMessage tokenResponse = client.PostAsync(baseAddress, contentString).Result;//Erro ocorre nesta linha
var jsonContent = tokenResponse.Content.ReadAsStringAsync().Result;
return jsonContent;
}
catch (Exception e)
{
return e.InnerException.Message.ToString();
}
}
From what I researched, and discovered from this error, means that the connection is being closed either by the server or by the client, but I can't even know who closes the connection suddenly let alone prevent this / exception error, I don't know if it matters but I am testing the app on an android 4.2-API 17 tablet. Thanks in advance for any guidance on this as I am still learning how to program in C #.
one thing I forgot to say before was that Postman API requests work without problems
I noticed something interesting the error I get only occurs when trying to send images larger than 100 kb by http request, how can I increase the send and receive weight limit on my server?

Firstly, you need to use await instead of Result() to make this method async:
var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
And yes, this exception occurs when internet connection is lost. You can do these things to make your app more usable:
Display a warning message in try-catch block
Check internet connection by using Xamarin.Essentials.Connectivity plugin
Set a timeout for your HttpClient object and catch the TimeoutException to display proper message

Related

Xamarin Forms - Epub: System.AggregateException: One or more errors occurred

I am converting my epub file URL to stream and saving to local DB as bytes like below:
Stream stream;
HttpClient client = new HttpClient();
var response = await client.GetAsync(fileUrl);
stream = await response.Content.ReadAsStreamAsync();
epubBook = EpubReader.ReadBook(stream);
//saving to folder
byte[] bytes = await response.Content.ReadAsByteArrayAsync();
string filename = Path.GetFileName(fileUrl);
var folderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filePath = Path.Combine(folderPath, filename);
File.WriteAllBytes(filePath, bytes);
This is working fine for most of the files. But some file URLs showing System.AggregateException.
Exception Details
System.AggregateException: One or more errors occurred. (Version number '1.1' is invalid. Line 1, position 16.) ---> System.Xml.XmlException: Version number '1.1' is invalid. Line 1, position 16.
at System.Xml.XmlTextReaderImpl.Throw (System.Exception e) [0x00027] in <0757e7484a1349cca3b4558c721885b2>:0
at System.Xml.XmlTextReaderImpl.Throw (System.String res, System.String arg) [0x00029] in <0757e7484a1349cca3b4558c721885b2>:0
at System.Xml.XmlTextReaderImpl.ParseXmlDeclaration (System.Boolean isTextDecl) [0x0061f] in <0757e7484a1349cca3b4558c721885b2>:0
at System.Xml.XmlTextReaderImpl.Read () [0x000c6] in <0757e7484a1349cca3b4558c721885b2>:0
at System.Xml.Linq.XDocument.Load (System.Xml.XmlReader reader, System.Xml.Linq.LoadOptions options) [0x00016] in <89374192b20a41739cf7c5bb822846fe>:0
at System.Xml.Linq.XDocument.Load (System.IO.Stream stream, System.Xml.Linq.LoadOptions options) [0x0000f] in <89374192b20a41739cf7c5bb822846fe>:0
at System.Xml.Linq.XDocument.Load (System.IO.Stream stream) [0x00000] in <89374192b20a41739cf7c5bb822846fe>:0
at VersOne.Epub.Internal.XmlUtils+<>c__DisplayClass0_0.b__0 () [0x00000] in <7c46dbfe3ebf403389304a938822832e>:0
at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <46c2fa109b574c7ea6739f9fe2350976>:0
at System.Threading.Tasks.Task.Execute () [0x00000] in <46c2fa109b574c7ea6739f9fe2350976>:0
--- End of stack trace from previous location where exception was thrown ---
Sample file URLs having this issue:
https://s3.us-east-1.amazonaws.com/catholic-brain/prod/dc/cbrain-app/files/doc-lib/2020/08/10/12/56/42/068/head/9781612781495_EPUB.epub
https://s3.us-east-1.amazonaws.com/catholic-brain/prod/dc/cbrain-app/files/doc-lib/2020/08/10/07/36/06/376/head/9781612781358_EPUB.epub
I am using EpubReader.Cross Nuget for parsing the epub file.
I have uploaded a sample project for the easy reference.

Dotmim.Sync SqliteSyncProvider is throwing exception in Xamarin IOS | Offline Sync

I am trying to use Dotmim.Sync with my Xamarin IOS project.
I have added a .net standard 2.0 project in my solution. Added Dotmim.Sync.Sqlite & Dotmim.Sync.Web.Client nuggets.
Here is the SyncService code:
public async Task SyncAsync()
{
var proxyClientProvider = new WebClientOrchestrator("https://localhost:44358/api/sync");
var clientProvider = new SqliteSyncProvider("mymobile.db");
var progress = new SynchronousProgress<ProgressArgs>(s => Console.WriteLine($"{s.Context.SyncStage}:\t{s.Message}"));
var agent = new SyncAgent(clientProvider, proxyClientProvider);
do
{
// Launch the sync process
var s1 = await agent.SynchronizeAsync(progress);
// Write results
Console.WriteLine(s1);
} while (Console.ReadKey().Key != ConsoleKey.Escape);
Console.WriteLine("End");
}
I have added that .net standard project reference into my iOS project and called the Sync Service class (just for the POC).
mButton.TouchUpInside += (sender, e) =>
{
SyncService sync = new SyncService();
Sync. SyncAsync ();
};
at
var s1 = await agent.SynchronizeAsync(progress);
It's throwing an exception:
System.NullReferenceException: Object reference not set to an instance of an object
at SQLitePCL.raw.sqlite3_open_v2 (SQLitePCL.utf8z filename, SQLitePCL.sqlite3& db,
System.Int32 flags, SQLitePCL.utf8z vfs) [0x00000] in <15ecb38d58394d7b88b3f841a7dda078>:0
at SQLitePCL.raw.sqlite3_open_v2 (System.String filename, SQLitePCL.sqlite3& db,
System.Int32 flags, System.String vfs) [0x0000e] in <15ecb38d58394d7b88b3f841a7dda078>:0
At Microsoft. Data. Sqlite. SqliteConnection. Open () [0x00122] in
<9ffe4c48f3134a7b905b5da527410f26>:0
at System.Data.Common.DbConnection.OpenAsync (System.Threading.CancellationToken
cancellationToken) [0x00011] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.0/src/Xamarin.iOS/external/corefx/src/. System.Data.Common/src/System/Data/Common/DbConnection.cs:122
--- End of stack trace from previous location where exception was thrown ---
And System.Console.ReadKey gives 'Operation is not supported on this platform.'
Any suggestion/help is welcome.
You should use SQLitePCL.Batteries_V2.Init();
This is part of the Xamarin limitations. More information here : https://learn.microsoft.com/en-us/dotnet/standard/data/sqlite/xamarin
Regarding Dotmim.Sync, see more informaition here : https://github.com/Mimetis/Dotmim.Sync/issues/249#issuecomment-609025301

C# Blazor WASM | Firestore: Receiving Mixed Content error when using Google.Cloud.Firestore.FirestoreDb.CreateAsync

Trying to create a FirebaseDb object in C# (Blazor WASM) is throwing a Blocked mixed content error after it's deployed to Firebase.
Is there a way to force this to use HTTPS?
The errror:
Blocked loading mixed active content “http://169.254.169.254/”
dotnet.3.2.0-preview3.20168.1.js:1:163131
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] blazor.webassembly.js:1:36074
Unhandled exception rendering component: TypeError: NetworkError when attempting to fetch resource. blazor.webassembly.js:1:36074
WebAssembly.JSException: TypeError: NetworkError when attempting to fetch resource. blazor.webassembly.js:1:36074
at WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler.doFetch (System.Threading.Tasks.TaskCompletionSource1[TResult] tcs, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x257c7e0 + 0x00988> in <filename unknown>:0 blazor.webassembly.js:1:36074
at WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x255e648 + 0x00184> in <filename unknown>:0 blazor.webassembly.js:1:36074
at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) <0x256c970 + 0x00278> in :0 blazor.webassembly.js:1:36074
at Google.Apis.Auth.OAuth2.ComputeCredential.IsRunningOnComputeEngineNoCache () <0x24f5570 + 0x0018c> in :0 blazor.webassembly.js:1:36074
at Google.Apis.Auth.OAuth2.DefaultCredentialProvider.CreateDefaultCredentialAsync () <0x24e22f0 + 0x0020e> in :0 blazor.webassembly.js:1:36074
at Google.Api.Gax.Grpc.ChannelPool.CreateChannelCredentialsUncached () <0x24cf210 + 0x000d8> in :0 blazor.webassembly.js:1:36074
at Google.Api.Gax.Grpc.ChannelPool.GetChannelAsync (Google.Api.Gax.Grpc.ServiceEndpoint endpoint, System.Collections.Generic.IEnumerable`1[T] channelOptions) <0x246fb30 + 0x000f4> in :0 blazor.webassembly.js:1:36074
at Google.Cloud.Firestore.V1.FirestoreClient.CreateAsync (Google.Api.Gax.Grpc.ServiceEndpoint endpoint, Google.Cloud.Firestore.V1.FirestoreSettings settings) <0x246e908 + 0x000ec> in :0 blazor.webassembly.js:1:36074
at Google.Cloud.Firestore.FirestoreDb.CreateAsync (System.String projectId, Google.Cloud.Firestore.V1.FirestoreClient client) <0x2449d00 + 0x001d0> in :0 blazor.webassembly.js:1:36074
at blog.Pages.Index.OnInitializedAsync () <0x2434eb8 + 0x000c8> in :0 blazor.webassembly.js:1:36074
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x2330b40 + 0x0014c> in :0 blazor.webassembly.js:1:36074
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x247d5b8 + 0x000c2> in :0 blazor.webassembly.js:1:36074
The code:
protected override async Task OnInitializedAsync()
{
string projectId = "my-poject-id";
FirestoreDb db = await FirestoreDb.CreateAsync(projectId);
}
TL;DR
The Firestore library is not supposed to be run within the browser context. It's developed to be used server-side or maybe in an admin tool. The library will allow you to do everything in Firestore and shipping the credentials to customers would be a security risk.
Based on your stacktrace I'm assuming you're using the Google.Cloud.Firestore library.
Unfortunately, this library is designed to be a "server client library". A client library to be used server side.
These "server client libraries" are designed differently than the "mobile/web client libraries".
The mobile/web libraries will use Firebase's authentication (username/password, Facebook, etc) and the security model will be applied on that user context.
The server libraries essentially give you access to everything.
Now the issues you're running into are caused by this SDK not being supported on Blazor.
First of all, the GOOGLE_APPLICATION_CREDENTIALS environment variable that the SDK relies on won't be available inside your Blazor application.
If it were available, the file wouldn't be accessible from within the browser sandbox.
You can circumvent both issues by using the FirestoreDbBuilder and setting the JsonCredentials and ProjectId manually like this:
var builder = new FirestoreDbBuilder();
builder.JsonCredentials = "{\"type\": \"service_account\", \"project_id\": \"\", \"private_key_id\": \"\", \"private_key\": \"\", \"client_email\": \"\", \"client_id\": \"\", \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\", \"token_uri\": \"https://oauth2.googleapis.com/token\", \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\", \"client_x509_cert_url\": \"\" }";
builder.ProjectId = "";
FirestoreDb db = builder.Build();
This will result into the next issue, the GRPC library used doesn't support Blazor/.NET WASM resulting in this stacktrace:
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Unsupported platform.
System.InvalidOperationException: Unsupported platform.
at Grpc.Core.Internal.NativeExtension.GetNativeLibraryFilename () [0x0003f] in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\NativeExtension.cs:231
at Grpc.Core.Internal.NativeExtension.LoadUnmanagedLibrary () [0x0000a] in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\NativeExtension.cs:93
at Grpc.Core.Internal.NativeExtension.LoadNativeMethods () [0x0001a] in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\NativeExtension.cs:120
at Grpc.Core.Internal.NativeExtension..ctor () [0x00006] in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\NativeExtension.cs:40
at Grpc.Core.Internal.NativeExtension.Get () [0x00022] in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\NativeExtension.cs:65
at Grpc.Core.Internal.NativeMethods.Get () [0x00000] in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\NativeMethods.cs:49
at Grpc.Core.GrpcEnvironment.GrpcNativeInit () [0x00016] in T:\src\github\grpc\src\csharp\Grpc.Core\GrpcEnvironment.cs:373
at Grpc.Core.GrpcEnvironment..ctor () [0x0001e] in T:\src\github\grpc\src\csharp\Grpc.Core\GrpcEnvironment.cs:302
at Grpc.Core.GrpcEnvironment.AddRef () [0x00028] in T:\src\github\grpc\src\csharp\Grpc.Core\GrpcEnvironment.cs:78
at Grpc.Core.Channel..ctor (System.String target, Grpc.Core.ChannelCredentials credentials, System.Collections.Generic.IEnumerable`1[T] options) [0x00041] in T:\src\github\grpc\src\csharp\Grpc.Core\Channel.cs:70
at Google.Api.Gax.Grpc.GrpcCore.GrpcCoreAdapter.CreateChannelImpl (System.String endpoint, Grpc.Core.ChannelCredentials credentials, Google.Api.Gax.Grpc.GrpcChannelOptions options) [0x00000] in T:\src\github\gax-dotnet\releasebuild\Google.Api.Gax.Grpc.GrpcCore\GrpcCoreAdapter.cs:34
at Google.Api.Gax.Grpc.GrpcAdapter.CreateChannel (System.String endpoint, Grpc.Core.ChannelCredentials credentials, Google.Api.Gax.Grpc.GrpcChannelOptions options) [0x00024] in T:\src\github\gax-dotnet\releasebuild\Google.Api.Gax.Grpc\GrpcAdapter.cs:29
at Google.Api.Gax.Grpc.ClientBuilderBase`1[TClient].CreateChannel (System.String endpoint, Grpc.Core.ChannelCredentials credentials) [0x00000] in T:\src\github\gax-dotnet\releasebuild\Google.Api.Gax.Grpc\ClientBuilderBase.cs:423
at Google.Api.Gax.Grpc.ClientBuilderBase`1[TClient].CreateCallInvokerAsync (System.Threading.CancellationToken cancellationToken) [0x00145] in T:\src\github\gax-dotnet\releasebuild\Google.Api.Gax.Grpc\ClientBuilderBase.cs:313
at Google.Cloud.Firestore.V1.FirestoreClientBuilder.BuildAsyncImpl (System.Threading.CancellationToken cancellationToken) [0x00033] in /_/apis/Google.Cloud.Firestore.V1/Google.Cloud.Firestore.V1/FirestoreClient.g.cs:285
at Google.Cloud.Firestore.FirestoreDbBuilder.BuildAsync (System.Threading.CancellationToken cancellationToken) [0x0015a] in /_/apis/Google.Cloud.Firestore/Google.Cloud.Firestore/FirestoreDbBuilder.cs:119
at BlazorFirestore.Pages.FetchData.OnInitializedAsync () [0x00061] in C:\Users\niels\source\repos\BlazorFirestore\Pages\FetchData.razor:12
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x2ff3be8 + 0x0013a> in <filename unknown>:0
This can be resolved by using Grpc.Net.Client.Web which is a Grpc implementation for .NET that works inside Blazor.
Create the following class (inspired on Google's Source):
using System;
using Grpc.Core;
using Google.Api.Gax.Grpc;
using Grpc.Net.Client;
using System.Net.Http;
using Grpc.Net.Client.Web;
// you'll need these packages
// Google.Apis.Auth, Google.Cloud.Firestore, Grpc.Net.Client, Grpc.Net.Client.Web
namespace BlazorFirestore
{
// most of the code was borrowed from https://github.com/googleapis/gax-dotnet/blob/master/Google.Api.Gax.Grpc.GrpcNetClient/GrpcNetClientAdapter.cs
public sealed class GrpcWebAdapter : GrpcAdapter
{
// this HttpClient using the GrpcWebHandler and mode is crucial to get Grpc to work for Firestore
private static HttpClient httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
// Note: this is "Default" rather than "Instance" as we expect to have other factory methods later, e.g. accepting
// an HTTP client factory.
/// <summary>
/// Returns the default instance of this class.
/// </summary>
public static GrpcWebAdapter Default { get; } = new GrpcWebAdapter();
private GrpcWebAdapter()
{
}
/// <inheritdoc />
protected override ChannelBase CreateChannelImpl(string endpoint, ChannelCredentials credentials, Google.Api.Gax.Grpc.GrpcChannelOptions options)
{
var grpcNetClientOptions = ConvertOptions(credentials, options);
var address = ConvertEndpoint(endpoint);
return GrpcChannel.ForAddress(address, grpcNetClientOptions);
}
// Internal for testing
internal static global::Grpc.Net.Client.GrpcChannelOptions ConvertOptions(ChannelCredentials credentials, Google.Api.Gax.Grpc.GrpcChannelOptions options)
{
// If service config resolution is explicitly enabled, throw - we can't support that,
// and users may be depending on it.
if (options.EnableServiceConfigResolution == true)
{
throw new ArgumentException($"{nameof(options.EnableServiceConfigResolution)} is not currently supported in {nameof(GrpcWebAdapter)}");
}
if (options.CustomOptions.Count > 0)
{
throw new ArgumentException($"Custom options are not currently supported in {nameof(GrpcWebAdapter)}");
}
// Options we ignore:
// - PrimaryUserAgent
// - KeepAliveTime
return new global::Grpc.Net.Client.GrpcChannelOptions
{
Credentials = credentials,
MaxReceiveMessageSize = options.MaxReceiveMessageSize,
MaxSendMessageSize = options.MaxSendMessageSize,
// pass the GrpcWeb version of the httpclient
HttpClient = httpClient
};
}
// Internal for testing
internal static string ConvertEndpoint(string endpoint) =>
// Note that we assume HTTPS for any bare address; this feels like a reasonable assumption for now.
endpoint.StartsWith("http:", StringComparison.Ordinal) || endpoint.StartsWith("https:", StringComparison.Ordinal)
? endpoint : $"https://{endpoint}";
}
}
Now set GrpcWebAdapter.Default to the FirestoreDbBuilder.GrpcAdapter:
var builder = new FirestoreDbBuilder();
builder.JsonCredentials = "{\"type\": \"service_account\", \"project_id\": \"\", \"private_key_id\": \"\", \"private_key\": \"\", \"client_email\": \"\", \"client_id\": \"\", \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\", \"token_uri\": \"https://oauth2.googleapis.com/token\", \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\", \"client_x509_cert_url\": \"\" }";
builder.ProjectId = "";
builder.GrpcAdapter = GrpcWebAdapter.Default;
FirestoreDb db = builder.Build();
DocumentReference docRef = db.Collection("users").Document("alovelace");
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "First", "Ada" },
{ "Last", "Lovelace" },
{ "Born", 1815 }
};
await docRef.SetAsync(user);
We get one step closer, but now we run into CORS security issues since this way of communicating with Firestore wasn't designed to run from a browser and there's no way to configure CORS combined with this SDK.
These are the resulting errors:
Access to fetch at 'https://firestore.googleapis.com/google.firestore.v1.Firestore/Commit' from origin 'https://localhost:5001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
dotnet.3.2.0.js:1 POST https://firestore.googleapis.com/google.firestore.v1.Firestore/Commit net::ERR_FAILED
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Status(StatusCode="Internal", Detail="Error starting gRPC call. JSException: TypeError: Failed to fetch", DebugException="WebAssembly.JSException: TypeError: Failed to fetch
at System.Net.Http.WebAssemblyHttpHandler.doFetch (System.Threading.Tasks.TaskCompletionSource`1[TResult] tcs, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x3c61b60 + 0x00a30> in <filename unknown>:0
at System.Net.Http.WebAssemblyHttpHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x3c24040 + 0x00174> in <filename unknown>:0
at Grpc.Net.Client.Web.GrpcWebHandler.SendAsyncCore (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x00092] in /_/src/Grpc.Net.Client.Web/GrpcWebHandler.cs:137
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) <0x3d9ae50 + 0x00134> in <filename unknown>:0
at Grpc.Net.Client.Internal.GrpcCall`2[TRequest,TResponse].RunCall (System.Net.Http.HttpRequestMessage request, System.Nullable`1[T] timeout) [0x0020c] in /_/src/Grpc.Net.Client/Internal/GrpcCall.cs:477 ")
Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error starting gRPC call. JSException: TypeError: Failed to fetch", DebugException="WebAssembly.JSException: TypeError: Failed to fetch
at System.Net.Http.WebAssemblyHttpHandler.doFetch (System.Threading.Tasks.TaskCompletionSource`1[TResult] tcs, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x3c61b60 + 0x00a30> in <filename unknown>:0
at System.Net.Http.WebAssemblyHttpHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x3c24040 + 0x00174> in <filename unknown>:0
at Grpc.Net.Client.Web.GrpcWebHandler.SendAsyncCore (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x00092] in /_/src/Grpc.Net.Client.Web/GrpcWebHandler.cs:137
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) <0x3d9ae50 + 0x00134> in <filename unknown>:0
at Grpc.Net.Client.Internal.GrpcCall`2[TRequest,TResponse].RunCall (System.Net.Http.HttpRequestMessage request, System.Nullable`1[T] timeout) [0x0020c] in /_/src/Grpc.Net.Client/Internal/GrpcCall.cs:477 ")
at Google.Api.Gax.Grpc.ApiCallRetryExtensions+<>c__DisplayClass0_0`2[TRequest,TResponse].<WithRetry>b__0 (TRequest request, Google.Api.Gax.Grpc.CallSettings callSettings) [0x00051] in T:\src\github\gax-dotnet\releasebuild\Google.Api.Gax.Grpc\ApiCallRetryExtensions.cs:27
at Google.Cloud.Firestore.WriteBatch.CommitAsync (Google.Protobuf.ByteString transactionId, System.Threading.CancellationToken cancellationToken) [0x000b5] in /_/apis/Google.Cloud.Firestore/Google.Cloud.Firestore/WriteBatch.cs:231
at Google.Cloud.Firestore.DocumentReference.SetAsync (System.Object documentData, Google.Cloud.Firestore.SetOptions options, System.Threading.CancellationToken cancellationToken) [0x0004b] in /_/apis/Google.Cloud.Firestore/Google.Cloud.Firestore/DocumentReference.cs:181
at BlazorFirestore.Pages.FetchData.OnInitializedAsync () [0x00166] in C:\Users\niels\source\repos\BlazorFirestore\Pages\FetchData.razor:21
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x2ff3be8 + 0x0013a> in <filename unknown>:0
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x3905a50 + 0x000b6> in <filename unknown>:0
When you explicitly disable CORS in your browser using .\chrome.exe --disable-web-security, then the result will be a successful authentication but the actual API's will return 404.
Why it returns 404 is unclear to me. I can sniff the Grpc.Net.Client.Web version with Fiddler, but the default implementation does not get intercepted by Fiddler.
It looks like the web-version uses a different protocol/transport that isn't supported or something. Hopefully somebody can resolve the next issue.
Conclusion: Firestore library for .NET isn't supposed to be used in the browser sandbox and isn't supported that way.
Currently, you'll need to use JS-Interop: https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet
p.s. as nicely pointed by #swimburger the server side C# doesn't work; this may change if a new client-side C# library will be added for firebase.

app_offline.htm file being used to take webservice offline - possible to read contents of file?

I'm using an app_offline.htm file as described here : http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx to take an old asmx web service offline.
All works fine, and the client end gets a HTTP 503 exception like :
Exception : System.Net.WebException
The request failed with HTTP status 503: Service Unavailable.
Source : System.Web.Services
Stack trace :
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
My question : is it possible for the client application to read the contents of the app_offline.htm file which would have been returned ? The basic HTML in that file has helpful text like : "The application is currently undergoing maintenance". I can see the contents of this file being returned in the response using Fiddler.
It would be useful to be able to parse this html response to provide more info to the user. (i.e. so it is possible to distinguish between a 503 error due to system maintenance, and other 503s due to system being overloaded etc).
EDIT : BluesRockAddict's response sounded good, but the stream seems to be unavailable at this time. e.g. :
// wex is the caught System.Net.WebException
System.Net.WebResponse resp = wex.Response;
byte[] buff = new byte[512];
Stream st = resp.GetResponseStream();
int count = st.Read(buff, 0, 512);
The last line above which attempts to read the stream gives :
Exception : System.ObjectDisposedException
Cannot access a closed Stream.
Source : mscorlib
Stack trace :
at System.IO.__Error.StreamIsClosed()
at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
credit goes to BluesRockAddict, adding to his answer, this is how you can read the content of html page.
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.ServiceUnavailable)
{
using (Stream stream = ex.Response.GetResponseStream())
{
using(StreamReader reader = new StreamReader(stream))
{
var message = reader.ReadToEnd();
}
}
}
}
You should use WebException.Response to retrieve the message:
using (WebClient wc = new WebClient())
{
try
{
string content = wc.DownloadString(url);
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.ServiceUnavailable)
{
message = ex.Response
}
}
}

CRM 2011 Dicovery Service FaultException

I have asked the same question at http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/d5d00302-8f7b-4efc-873b-c54b3e29749d but didn't get an answer. So, I will give another try at stackoverflow.
I was running the example code from the crm 2011 training kit.
var creds = new ClientCredentials();
var dsp = new DiscoveryServiceProxy( dinfo, creds);
dsp.Authenticate();
var orgRequest = new RetrieveOrganizationRequest();
var response = dsp.Execute(orgRequest);
var orgResponse = response as RetrieveOrganizationsResponse;
if (orgResponse != null)
comboOrgs.ItemsSource = orgResponse.Details;
At the line of var response = dsp.Execute(orgRequest), I got the FaltException`1, the detailed message is as follows
System.ServiceModel.FaultException`1 was unhandled
Message=organizationName
Source=mscorlib
Action=http://schemas.microsoft.com/xrm/2011/Contracts/Discovery/IDiscoveryService/ExecuteDiscoveryServiceFaultFault
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.Xrm.Sdk.Discovery.IDiscoveryService.Execute(DiscoveryRequest request)
at Microsoft.Xrm.Sdk.Client.DiscoveryServiceProxy.Execute(DiscoveryRequest request)
I was able to access the Discovery.svc file using browser. So the server url should be correct. Is this an authentication problem?
Is this for Microsoft CRM Online or on-premise? For Online, I know you would want to use something along the lines of what is found in the SDK -
// Connect to the Discovery service.
// The using statement assures that the service proxy will be properly disposed.
using (DiscoveryServiceProxy _serviceProxy = new DiscoveryServiceProxy(serverConfig.DiscoveryUri,
serverConfig.HomeRealmUri,
serverConfig.Credentials,
serverConfig.DeviceCredentials))
{
// You can choose to use the interface instead of the proxy.
IDiscoveryService service = _serviceProxy;
#region RetrieveOrganizations Message
// Retrieve details about all organizations discoverable via the
// Discovery service.
RetrieveOrganizationsRequest orgsRequest =
new RetrieveOrganizationsRequest()
{
AccessType = EndpointAccessType.Default,
Release = OrganizationRelease.Current
};
RetrieveOrganizationsResponse organizations =
(RetrieveOrganizationsResponse)service.Execute(orgsRequest);
}
There are overloads for the DiscoveryServiceProxy class but if you provide some more details on what you are trying to connect to, I think it will narrow it down.

Resources