For Blazor WebAssembly I came up with the idea of using SQLite. This question mentions it is not possible. Is it possible to use SQLite in Blazor WebAssembly and if so, how?
As of .NET 6, you can use include native dependencies in Blazor WebAssembly, one example in fact being SQLite. See example code here: https://github.com/SteveSandersonMS/BlazeOrbital/blob/6b5f7892afbdc96871c974eb2d30454df4febb2c/BlazeOrbital/ManufacturingHub/Properties/NativeMethods.cs#L6
Starting .Net 6, it is now possible to use SQLite with Blazor Web Assembly .
Here are the steps,
Add reference to following Nuget packages.
a. Microsoft.EntityFrameworkCore.Sqlite
b. SQLitePCLRaw.bundle_e_sqlite3 - Currently in preview as of posting this answer. This package is to avoid NativeFileReference of e_sqlite3.o.
Add the following in .csproj to avoid unwanted warning from popping out.
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EmccExtraLDFlags>-s WARN_ON_UNDEFINED_SYMBOLS=0</EmccExtraLDFlags>
Add the following code in Program.cs. This is required to avoid runtime exception - Could not find method 'AddYears' on type 'System.DateOnly'
public partial class Program
{
/// <summary>
/// FIXME: This is required for EF Core 6.0 as it is not compatible with trimming.
/// </summary>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
private static Type _keepDateOnly = typeof(DateOnly);
}
I'm using sqlite inmemory store. Here is the Code Example.
Database Model:
public class Name
{
public int Id { get; set; }
public string FullName { get; set; }
}
Database Context:
public class TestDbCOntext : DbContext
{
public DbSet<Name> Names { get; set; } = default!;
public TestDbCOntext(DbContextOptions<TestDbCOntext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Name>().ToTable("Names");
modelBuilder.Entity<Name>().HasIndex(x => x.FullName);
modelBuilder.Entity<Name>().Property(x => x.FullName).UseCollation("nocase");
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.LogTo(Console.WriteLine, LogLevel.Warning)
.EnableDetailedErrors()
.EnableSensitiveDataLogging(true);
}
}
Page/Component:
<button #onclick="RunEfCore">Run Ef Core</button>
#code {
private async Task RunEfCore()
{
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" };
var connection = new SqliteConnection(connectionStringBuilder.ToString());
var options = new DbContextOptionsBuilder<TestDbCOntext>()
.UseSqlite(connection)
.Options;
using var db = new TestDbCOntext(options);
db.Database.OpenConnection();
await db.Database.EnsureCreatedAsync();
var nextId = db.Names!.Count() + 1;
db.Names.Add(new Name { Id = nextId, FullName = "Abdul Rahman" });
await db.SaveChangesAsync();
Console.WriteLine();
await foreach (var name in db.Names.AsAsyncEnumerable())
{
Console.WriteLine(name.FullName);
}
db.Database.CloseConnection();
}
}
For persistance, you can make use of IndexedDB from browser and sync to save in your server.
Sample Working Demo can found in my Github Repo - BlazorWasmEfCore
Live Demo
Refer the github issue for complete history.
Steve Sanderson Video Reference
Screenshot:
Points to consider:
The below details are taken from following stackoverflow answer.
A good rule of programming is KISS - Keep it Simple. So if the requirement of your app is satisfied by Linq to Objects, then complicating it with SQLite would seem to be the wrong thing to do.
However, in the video Steve S. does come up with requirement parameters that lend themselves to using SQLite - the application needs to process:
lots of data
in the client
offline
quickly
The use of SQLite here is not for persisting beyond client app memory.
So the answer to your question on the advantage of a Blazor app using SQLite is simply:
If an app needs the functionality of an in-memory relational database but is trying to avoid using one, it will either be reinventing the wheel in its implementation, or missing necessary functionality.
If an app doesn't need the functionality of an in-memory database but is using one, it will be introducing unnecessary complexity (cost).
Your Blazor WebAssembly C# code still runs in the sandbox of the browser, that means it is not allowed to open files on the local drive.
Blazor WebAssembly has the same access to the machine as any regular website.
Even if someone was to port SQLite to WebAssembly you would not be able to open a database file.
For storage on the client computer you are limited to Local Storage, it is limited to 5 MB (might be different per browser brand) and can only contain strings. But it is not a reliable option as the data will be removed when the users clears the cache, browser history etc..
The only option you have is storing data on the server.
I am a little embarrassed asking this question here since for anyone who has done this the answer will be real simple. I have tried several times asking Stripe Support but they simply keep referring me to the documentation (which is incomplete). I am building my first integration to the Stripe Billing Portal https://stripe.com/docs/billing/subscriptions/integrating-customer-portal using .Net
The code snippet below is taken from their site and it references the class SessionCreateOptions. My simple question is "what is the fully qualified namespace to this class in Stripe" as Visual Studio Cannot find it.
StripeConfiguration.ApiKey = "sk_test_47ZQVRjCoUpDACp40ICpzZKA00qYqRydc0";
[HttpPost("create-customer-portal-session")]
public async Task<IActionResult> CustomerPortal()
{
// Authenticate your user.
var options = **new SessionCreateOptions**
{
Customer = "{{ CUSTOMER_ID }}",
ReturnUrl = "https://example.com/account",
};
var service = new SessionService();
var session = service.Create(options);
return Response.Redirect(session.Url);
}
Many thanks in advance for any help
I'm trying to develop a program that handles POST and GET requests.
I've spent countless hours searching around the web for a tutorial that doesn't depend on ASP.NET I do not want to use ASP.NET just standard C#.
How can I achieve this? The furthest I've gotten to is this:
if (HttpMethod.ContentType == "POST") {
// Code here
}
I've made a function HttpListen server on http://localhost:8080/ which sends a response.
What I'm looking for is you do http://localhost:8080/?method=val1&results=val2.
Thanks, Brown.
You're looking for an HTTP server library that is not ASP.NET?
Awkwardly bypassing the question "What's wrong with ASP.NET?"....
Nancy is an awesome lightweight open source library. You can find some samples on github, although the samples are a bit on the heavy side. If you're looking for an extremely basic setup you can get away with a couple dozen lines of code. A good example is the console-based self-hosted sample.
// add such a module class to your assembly, Nancy should find it automagically
public class ResourceModule : NancyModule
{
public ResourceModule() : base("/products")
{
// would capture routes to /products/list sent as a GET request
Get["/list"] = parameters => {
return "The list of products";
};
}
}
// then start the host
using (var host = new NancyHost(new Uri("http://localhost:1234")))
{
host.Start();
// do whatever other work needed here because once the host is disposed of the server is gone
Console.ReadLine();
}
I followed this asp.net tutorial by Mike Wasson, and managed to set up the related entities just fine, but when I applied this logic to my project the more complex entity relations (in that there are more of them; that's the only difference) wouldn't succeed in an OData call, I got a 404 with this payload:
{
"error": {
"code": "",
"message": "No HTTP resource was found that matches the request URI 'http://localhost:19215/Menus(c94f7f98-6987-e411-8119-984be10349a2)/MenuPermissions'.",
"innererror": {
"message": "No routing convention was found to select an action for the OData path with template '~/entityset/key/unresolved'.",
"type": "",
"stacktrace": ""
}
}
}
The tutorial doesn't mention having to set up EdmModel navigations and Mike Wasson makes a point of pointing out that "asp.net is official documentation :-)"; so, I have spent a while trying to get these related entities working, thinking I had set up the project incorrectly.
I thought it might have something to do with the version of ASP.NET OData libraries that NuGet was installing (the NuGet Console installs 6.9.x, whereas the NuGet Dialog installs 6.5.x). I also wondered if it was because I set the project up as a completely empty project and then use OWIN, so I tried it with a pure ASP.NET templated solution. I also tried a couple of other possible solutions: OData-route-attributes on my controller methods; and including my data layer and models all in the same library (I have them separated out to keep DRY); I even attempted to use the WebApi route debugger by Rick Anderson - I wouldn't attempt to use this again!
All to no avail.
There was a brief moment when they worked, but I don't know why; they ceased to work on the next build/run - I guess I changed something in between, but it was very minor and I was losing confidence at every step.
Then I decided that Mike Wasson must've just taken the path of least resistance in his tutorial and so I reverted to this SO question/answer and modified it for use with ODataConventionModelBuilder and reuse, as I will explain in my answer below.
If anyone knows of a simpler way of getting this to work, please let me know, otherwise I recommend just biting the bullet and writing those EdmModel-Navigations in my answer below.
As I mention in the question, I tried many solutions to get this to work, but none were consistent in actually solving the problem and I kept avoiding the solution laid out in this SO question/answer because the tutorial is specifically for v4 and I figured that answer must be for an older version (how unwise).
So that answer does solve the problem, but requires some work to fit directly into OData v4 and an ODataConventionModelBuilder; this is why I have posted this question and answer; to provide a solution, specifically for OData v4 and ODataConventionModelBuilder, in the hope that others won't lose the time I have looking into this.
First, set up your EdmModel:
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();
builder.EntitySet<Menu>("Menus");
builder.EntitySet<MenuPermission>("MenuPermissions");
var edmModel = builder.GetEdmModel();
AddNavigations(edmModel); //see below for this method
return edmModel;
}
Second AddNavigations:
private static void AddNavigations(IEdmModel edmModel)
{
AddMenuPermissionsNavigation(edmModel);
}
private static void AddMenuPermissionsNavigation(IEdmModel edmModel)
{
var menus = (EdmEntitySet) edmModel.EntityContainer.FindEntitySet("Menus");
var menuPermissions = (EdmEntitySet)edmModel.EntityContainer.FindEntitySet("MenuPermissions");
var menuType = (EdmEntityType) edmModel.FindDeclaredType("iiid8.cms.data.models.Menu"); //"iiid8.cms.data.models" is the C# namespace
var menuPermissionType = (EdmEntityType)edmModel.FindDeclaredType("iiid8.cms.data.models.MenuPermission"); //as above, "iiid8.cms.data.models" is the C# namespace
AddOneToManyNavigation("MenuPermissions", menus, menuPermissions, menuType, menuPermissionType);
AddManyToOneNavigation("Menu", menus, menuPermissions, menuType, menuPermissionType);
}
private static void AddOneToManyNavigation(string navTargetName, EdmEntitySet oneEntitySet, EdmEntitySet manyEntitySet,
EdmEntityType oneEntityType, EdmEntityType manyEntityType)
{
var navPropertyInfo = new EdmNavigationPropertyInfo
{
TargetMultiplicity = EdmMultiplicity.Many,
Target = manyEntityType,
ContainsTarget = false,
OnDelete = EdmOnDeleteAction.None,
Name = navTargetName
};
oneEntitySet.AddNavigationTarget(oneEntityType.AddUnidirectionalNavigation(navPropertyInfo), manyEntitySet);
}
private static void AddManyToOneNavigation(string navTargetName, EdmEntitySet oneEntitySet, EdmEntitySet manyEntitySet,
EdmEntityType oneEntityType, EdmEntityType manyEntityType) {
var navPropertyInfo = new EdmNavigationPropertyInfo {
TargetMultiplicity = EdmMultiplicity.One,
Target = oneEntityType,
ContainsTarget = false,
OnDelete = EdmOnDeleteAction.None,
Name = navTargetName
};
manyEntitySet.AddNavigationTarget(manyEntityType.AddUnidirectionalNavigation(navPropertyInfo), oneEntitySet);
}
Finally, call GetEdmModel from WebApiConfig.Register
config.MapODataServiceRoute("odata", null, GetEdmModel());
Now call your OData service's one-to-many and many-to-one navigations from your client and all should be good with your world. In my case the calls look like this:
One-to-many:
http://localhost:19215/Menus(c94f7f98-6987-e411-8119-984be10349a2)/MenuPermissions
Many-to-one:
http://localhost:19215/MenuPermissions(ba0da52a-6c87-e411-8119-984be10349a2)/Menu
This answer assumes you set up the rest of your project just like Mike Wasson suggests in the tutorial linked in the question (that link is to Part 3 - you will need to follow Part 1 first!).
I am using ASP.NET 5, Web API 2.2, and Entity Framework.
Another developer and I have also spent hours trying to figure out why, after following that same tutorial to a T, we couldn't get a relational route like the following to return anything other than a 404:
/odata/Supplier(1)/Products
We also tried the route debugger referenced in the OP, and it failed to produce anything other than a blank screen.
Luckily, for our needs, one of our random experiments worked, and that was to use the ODataRoute attribute like such:
[EnableQuery]
[ODataRoute("Suppliers({key})/Products")]
public IQueryable<Product> GetProductsForSupplier([FromODataUri] int key)
{
...
}
I'm currently developing a web app using the open source Kendo UI Scheduler with ASP.NET MVC Visual Studio 2012. But i'm experiencing some trouble while trying to connect my scheduler with a local database to store the bookings made by users of my application.
I've been looking for documentation to help me with this but I haven't been able to set this up entirely...
I followed instructions about this on: http://docs.telerik.com/kendo-ui/getting-started/using-kendo-with/aspnet-mvc/helpers/scheduler/ajax-editing
I've added the Entity Framework Data Model and necessary code in Models like TaskViewModel but the problem occurs in my Controllers.
public ActionResult Tasks_Read([DataSourceRequest]DataSourceRequest request)
{
using (var sampleDB = new SchedulerEntities())
{
IQueryable<TaskViewModel> tasks = sampleDB.Tasks.ToList().Select(task => new TaskViewModel()
{
TaskID = task.TaskID,
Title = task.Title,
//Specify the DateTimeKind to be UTC
Start = Convert.ToDateTime(task.Start),
End = Convert.ToDateTime(task.End),
Description = task.Deschription,
}).AsQueryable();
return Json(tasks.ToDataSourceResult(request));
}
}
I get an error on the DataSourceRequest: the type or namespace DataSourceRequest could not be found. But I can't find to narrow down which module I'm missing or what else I'm doing wrong...
Besides that I also get the following error System.LinqIQueryable doest not contain a definition for ToDataSourceResult. on the code:
return Json(tasks.ToDataSourceResult(request));
Anyone who can help me here or has an other/better solution to make a connection to a local database using the open source Kendo UI Scheduler?
Any help would be really appreciated!
You need to specify the allow get behavior.
return Json(tasks.ToDataSourceResult(request), JsonRequestBehavior.AllowGet));