How to simply execute stored procedure in blazor server app? - stored-procedures

I am building a Blazor server app using a repository pattern and am trying to execute a stored procedure from a Razor component page.
However I am getting an error when I run it:
blazor.server.js:21 [2021-03-29T02:03:38.207Z] Error: System.InvalidOperationException: Cannot provide a value for property 'ICalculateImportanceService' on type 'ThePositionerBlazorServerDapperSyncfusion.Pages.DBProcessing.CalculateItemImportance'. There is no registered service of type 'ThePositionerBlazorServerDapperSyncfusion.Data.CalculateImportanceService'.
Not sure why I am getting the error because I believe I registered the service.
Here is the relevant code:
CalculateItemImportance.razor
#using ThePositionerBlazorServerDapperSyncfusion.Data
#page "/DBProcessing/calcultateitemImportance"
#inject CalculateImportanceService ICalculateImportanceService
#inject NavigationManager NavigationManager
<h1 style="text-align:center">#pagetitle</h1>
#code {
public string pagetitle = "Calculate Importance";
protected override async Task OnInitializedAsync()
{
// Kick off stored procedure to calculate importance
await ICalculateImportanceService.CalculateImportance();
}
}
ICalculateImportanceService.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ThePositionerBlazorServerDapperSyncfusion.Data;
namespace ThePositionerBlazorServerDapperSyncfusion.Data
{
public interface ICalculateImportanceService
{
Task<bool> CalculateImportance();
}
}
CalculateImportanceService.cs
using Dapper;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
namespace ThePositionerBlazorServerDapperSyncfusion.Data
{
public class CalculateImportanceService : ICalculateImportanceService
{
private readonly SqlConnectionConfiguration _configuration;
public CalculateImportanceService(SqlConnectionConfiguration configuration)
{
_configuration = configuration;
}
public async Task<bool> CalculateImportance()
{
using (var conn = new SqlConnection(_configuration.Value))
{
await conn.ExecuteAsync("CalculateTheItemImportance", commandType: CommandType.StoredProcedure);
}
return true;
}
}
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ThePositionerBlazorServerDapperSyncfusion.Data;
using Syncfusion.Blazor;
namespace ThePositionerBlazorServerDapperSyncfusion
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
//services.AddSingleton<WeatherForecastService>();
//Syncfusion support
services.AddSyncfusionBlazor();
services.AddControllers().AddNewtonsoftJson();
var sqlConnectionConfiguration = new SqlConnectionConfiguration(Configuration.GetConnectionString("SqlDBContext"));
services.AddSingleton(sqlConnectionConfiguration);
services.AddScoped<IApplicConfsService, ApplicConfsService>();
services.AddScoped<IPOSSUMMARYService, POSSUMMARYService>();
services.AddScoped<IPOSDETAILService, POSDETAILService>();
services.AddScoped<IDESCRIPTIONTYPEService, DESCRIPTIONTYPEService>();
services.AddScoped<IIMPService, IMPService>();
services.AddScoped<IITEMCATEGORYService, ITEMCATEGORYService>();
services.AddScoped<IKNOWDEPService, KNOWDEPService>();
services.AddScoped<IMembersService, MembersService>();
services.AddScoped<IPRDSRVService, PRDSRVService>();
services.AddScoped<IPROCESSESService, PROCESSESService>();
services.AddScoped<ITASKKNOService, TASKKNOService>();
services.AddScoped<ITMPOVERLAPService, TMPOVERLAPService>();
services.AddScoped<ITEXTUALService, TEXTUALService>();
services.AddScoped<ITIMESCALEService, TIMESCALEService>();
services.AddScoped<IWORKHIERService, WORKHIERService>();
services.AddScoped<ICalculateImportanceService, CalculateImportanceService>();
services.AddScoped<ICalculateFTEService, CalculateFTEService>();
}
}
}
The stored procedure has no parameters and simply executes processing on the database.
Any help would be appreciated. Thanks

Change
#inject CalculateImportanceService ICalculateImportanceService
to
#inject ICalculateImportanceService CalculateImportanceService
and further down
// await ICalculateImportanceService.CalculateImportance();
await CalculateImportanceService.CalculateImportance();

Related

Calling SignalR functions outside of Hub Class

I am are trying to get an instance of a Hub Class to call front-end methods from the backend from a class outside of the Hub class.
I am using IHostLifeTime that has a register function that will be running in the background while the server is running in a while loop.
There will be events in the while loop that will trigger signalR to send a message to the client.
Question: How am I supposed to get access to the hub and send a message to the client inside of my manager class in the ApplicationReady() function?
TestHub.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
namespace SignalREventHandle
{
public class TestHub : Hub
{
public async Task SendMessage(string user, string message)
{
Console.WriteLine($"user: {user} message:{message}");
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using System.Threading;
namespace SignalREventHandle
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request //pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, IHubContext<TestHub> hubContext)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
lifetime.ApplicationStarted.Register(OnAppStarted);
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<TestHub>("/testHub");
});
}
public async void OnAppStarted()
{
//Get Singleton Instance of Manager and then start the application
var manager = Manager.Instance;
manager.ApplicationReady();
}
}
}
Manager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
namespace SignalREventHandle
{
public class Manager
{
private bool _isServerRunning;
/// <summary>
/// Instance of class to implement Singleton
/// </summary>
private static readonly Manager _instance = new();
/// <summary>
/// Getter for Class instance
/// </summary>
public static Manager Instance
{
get => _instance;
}
public async void ApplicationReady()
{
var task = Task.Run(() =>
{
_isServerRunning = true;
while (_isServerRunning)
{
// Want to Send Message to Client with SignalR here
Thread.Sleep(10000);
}
});
}
}
}
In ASP.NET 4.x SignalR use GlobalHost to provide access to the IHubContext:
public static async Task SendMessage(string user, string message)
{
Console.WriteLine($"user: {user} message: {message}");
// Get an instance of IHubContext from GlobalHost
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
await hubContext.Clients.All.SendAsync("ReceiveMessage", user, message);
}
In ASP.NET Core SignalR, you can access an instance of IHubContext from the web host.
Program.cs
public class Program
{
public static IHost WebHost;
public static void Main(string[] args)
{
WebHost = CreateHostBuilder(args).Build();
WebHost.Run();
}
...
}
Then:
public static async Task SendMessage(string user, string message)
{
Console.WriteLine($"user: {user} message: {message}");
// Get an instance of IHubContext from IHost
var hubContext = Program.WebHost.Services.GetService(typeof(IHubContext<ChatHub>)) as IHubContext<ChatHub>;
await hubContext.Clients.All.SendAsync("ReceiveMessage", user, message);
}
Documentation:
https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-5.0
signalr how i can i post a message from server to caller

Stored procedure ADO.NET .NET Core Web API

I am building a Web API in ASP.NET Core, I am using stored procedures to be able to handle more complex queries, which with the Entity Framework is too complicated for me, I am using ADO.NET to make this connection.
I have managed to connect to a stored procedure and use the get and post methods, the point is that I don't know how to do it in order to call the other stored procedures and map a route to interact via get or post in the same project. I have only been able to do one, and I don't think it would be more convenient to create a Web API for each function that complies with a stored procedure.
My project is made up of three folders called Controller, Data, Models.
Within Models is the Value class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ASPNETCore_StoredProcs.Models
{
public class Value
{
public int Id { get; set; }
public int Value1 { get; set; }
public string Value2 { get; set; }
}
}
Data folder has a class called ValueRepository
using ASPNETCore_StoredProcs.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
namespace ASPNETCore_StoredProcs.Data
{
public class ValuesRepository
{
private readonly string _connectionString;
public ValuesRepository(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("defaultConnection");
}
public async Task<List<Value>> GetAll()
{
using (SqlConnection sql = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand("GetAllValues", sql))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
var response = new List<Value>();
await sql.OpenAsync();
using (var reader = await cmd.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
response.Add(MapToValue(reader));
}
}
return response;
}
}
}
private Value MapToValue(SqlDataReader reader)
{
return new Value()
{
Id = (int)reader["Id"],
Value1 = (int)reader["Value1"],
Value2 = reader["Value2"].ToString()
};
}
public async Task<Value> GetById(int Id)
{
using (SqlConnection sql = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand("GetValueById", sql))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#Id", Id));
Value response = null;
await sql.OpenAsync();
using (var reader = await cmd.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
response = MapToValue(reader);
}
}
return response;
}
}
}
public async Task Insert(Value value)
{
using (SqlConnection sql = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand("InsertValue", sql))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#value1", value.Value1));
cmd.Parameters.Add(new SqlParameter("#value2", value.Value2));
await sql.OpenAsync();
await cmd.ExecuteNonQueryAsync();
return;
}
}
}
public async Task DeleteById(int Id)
{
using (SqlConnection sql = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand("DeleteValue", sql))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#Id", Id));
await sql.OpenAsync();
await cmd.ExecuteNonQueryAsync();
return;
}
}
}
}
}
and finally I have a controller class called ValuesController:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ASPNETCore_StoredProcs.Data;
using ASPNETCore_StoredProcs.Models;
using Microsoft.AspNetCore.Mvc;
namespace ASPNETCore_StoredProcs.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ValuesRepository _repository;
public ValuesController(ValuesRepository repository)
{
this._repository = repository ?? throw new ArgumentNullException(nameof(repository));
}
// GET api/values
[HttpGet]
public async Task<ActionResult<IEnumerable<Value>>> Get()
{
return await _repository.GetAll();
}
// GET api/values/5
[HttpGet("{id}")]
public async Task<ActionResult<Value>> Get(int id)
{
var response = await _repository.GetById(id);
if (response == null) { return NotFound(); }
return response;
}
// POST api/values
[HttpPost]
public async Task Post([FromBody] Value value)
{
await _repository.Insert(value);
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public async Task Delete(int id)
{
await _repository.DeleteById(id);
}
}
}
This is my startup class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ASPNETCore_StoredProcs.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace ASPNETCore_StoredProcs
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ValuesRepository>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
I appreciate if you can help me or if it is how I think I should create an API for each procedure that is performed thanks

Appsettings and middleware Core 2.1

I have made a custom middleware and now I want to access the appsettings that are in another project in my solution. Should I inject the IConfiguration object into the middleware constructor, and add the using statement of Microsoft.Extensions.Configuration? Or is there a better way to do this?
I am working with ASP.net Web page with Core 2.1.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System;
using System.Threading.Tasks;
public class MyMiddleware
{
public IConfiguration _configuration;
public MyMiddleware(RequestDelegate next, IConfiguration config)
{
_next = next;
_ configuration = config;
}
If you don't need all your configuration passed to your middleware but just a section you can use
IOptions<T>
Create MyConfig.cs Class file:
public class MyConfig
{
public string MyConfig1 {get; set;}
public string MyConfig2 {get; set;}
}
In ConfigureServices method in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
}
In your middleware
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System;
using System.Threading.Tasks;
public class MyMiddleware
{
private readonly IOptions<MyConfig> _appSettings;
public MyMiddleware(RequestDelegate next, IOptions<MyConfig> config)
{
_next = next;
_configuration = config;
}
public MyMethod()
{
_configuration.Value.MyConfig1
}
}
In appsettings.json file:
{
"AppSettings": {
"AppId": "0001",
"AppName": "xxxx",
},
"MyConfig": {
"MyConfig1": "xxxxxxx",
"MyConfig2": "xxxxxxx",
},
}

I can't get ios data saved on its memory (xamarin.forms - interface)

app delegate:
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
// Get current device token
var DeviceToken = deviceToken.Description;
if (!string.IsNullOrWhiteSpace(DeviceToken))
{
DeviceToken = DeviceToken.Trim('<').Trim('>');
}
// Get previous device token
var oldDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey("token");
// Has the token changed?
if (string.IsNullOrEmpty(oldDeviceToken) || !oldDeviceToken.Equals(DeviceToken))
{
//TODO: Put your own logic here to notify your server that the device token has changed/been created!
}
// Save new device token
//NSUserDefaults.StandardUserDefaults.SetString(DeviceToken, "token");
IOSUserPreferences userPreference = new IOSUserPreferences();
userPreference.SetString("token", DeviceToken);
}
my PCL interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace neoFly_Montana
{
public interface IUserPreferences
{
void SetString(string key, string value);
string GetString(string key);
}
}
when I call the interface in pcl:
string token = App.UserPreferences.GetString("token");
App.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
namespace neoFly_Montana
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new Views.Splash2()) { BarTextColor = Color.FromHex("#f98e1e") };
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
public static IUserPreferences UserPreferences { get; private set; }
public static void Init(IUserPreferences userPreferencesImpl)
{
App.UserPreferences = userPreferencesImpl;
}
}
}
on iphone project:
using Foundation;
using System;
using System.Collections.Generic;
using System.Text;
namespace neoFly_Montana.iOS
{
class IOSUserPreferences : IUserPreferences
{
public void SetString(string key, string value)
{
NSUserDefaults.StandardUserDefaults.SetString(value, key);
}
public string GetString(string key)
{
return NSUserDefaults.StandardUserDefaults.StringForKey(key);
}
}
}
on Android it works fine, saves and gets the data...
as a test, I tried to save a data and get it on app delegate and it worked fine, I could see it accesing the IOSUserPreferences script, the problens occurs when I try to get it on pcl
when I try to get the data that is saved, only in ios, it's null and app crashes...I noticed that it doesn't access the get string method on iphone project...
Does someone know what is happening ?

No Definition for Plugin in XSockets.net

I am working on a RTC Project in ASP.net and using XSockets.net for signalling purpose in VS 2013. But as I install XSockets.net 4.1.0 and try to create Xsockets.Net.BootStrapper class under App_Start folder it comes up with an error that Project doesn't contain definition for Plugin.
BootStrapper.cs:
using System.Web;
using XSockets.Core.Common.Socket;
[assembly: PreApplicationStartMethod(typeof(RTC.App_Start.XSockets), "Start")]
namespace RTC.App_Start
{
public static class XSockets
{
private static IXSocketServerContainer container;
public static void Start()
{
container = XSockets.Plugin.Framework.Composable.GetExport<IXSocketServerContainer>();
container.Start();
}
}
}
Use this instead of yours
using System.Web;
using XSockets.Core.Common.Socket;
[assembly: PreApplicationStartMethod(typeof(XSockets.WebRTC.App_Start.XSocketsWebBootstrapper), "Start")]
namespace XSockets.WebRTC.App_Start
{
public static class XSocketsWebBootstrapper
{
private static IXSocketServerContainer container;
public static void Start()
{
container = XSockets.Plugin.Framework.Composable.GetExport<IXSocketServerContainer>();
container.Start();
}
}
}

Resources