Push data server to client web app, how to? - asp.net

(Regarding Web apps, asp.net 5)
I'm new to this stuff, i want to push data from the server to the client. Displaying 'real-time' data on a website. (something like a chat window).
How should i realize this? I've read about SingalR, but most information seems to be outdated? Is this still a good choice?
For example, one of the problems i run into is when i try to add this:
app.MapSignalR();
to my startup.cs
Error CS1061 'IApplicationBuilder' does not contain a definition for 'MapSignalR' and no extension method 'MapSignalR' accepting a first argument of type 'IApplicationBuilder' could be found
Can someone point me in the right direction?

I believe you can do this with a bridge between IAppBuilder and IApplicationBuilder as shown here:
public static IApplicationBuilder UseAppBuilder(this IApplicationBuilder app, Action<IAppBuilder> configure)
{
app.UseOwin(addToPipeline =>
{
addToPipeline(next =>
{
var appBuilder = new AppBuilder();
appBuilder.Properties["builder.DefaultApp"] = next;
configure(appBuilder);
return appBuilder.Build<AppFunc>();
});
});
return app;
}
Which you would then call from startup to start SignalR:
public void Configure(IApplicationBuilder app)
{
app.UseAppBuilder(appBuilder =>
{
appBuilder.MapSignalR();
appBuilder.Run(context =>
{
});
});
}
Some context, excerpted from the link above:
[In ASP.NET 5, now ASP.NET Core 1.0] the Startup class conventions
have been refined. Katana [the previous version] would search for an
assembly that specified the OwinStartup attribute and then fallback
to searching all assemblies for a class named Startup or
AssemblyName.Startup. ASP.NET does not define an attribute and it only
searches the primary application assembly for a type named Startup (in
any namespace). The Configuration(IAppBuilder app) method is now
Configure(IApplicationBuilder app)...
Middleware that can’t remove their IAppBuilder or OwinMiddleware
dependencies can use a modified approach to run in ASP.NET 5. See this
linked sample for an IApplicationBuilder extension that provides an
IAppBuilder for use with Katana v3 based middleware. This extension
creates a new AppBuilder instance and then wraps the OWIN pipeline
builder pattern around it to integrate into ASP.NET 5.

Related

Why doesn't middleware execute after mapping controllers?

I am building the most basic of an ASP.NET Core Web API, and after a lot of experimenting on my own, I found that running any middleware (custom, app.run, app.use) after the .MapControllers() method doesn't work at all.
internal class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoint =>
{
endpoint.MapControllers();
});
}
}
I'm asking here because the documentation didn't clarify: how does the MapControllers() method affect other middleware in the pipeline?
I found that running any middleware (custom, app.run, app.use) after
the .MapControllers() method doesn't work at all.
The issue might relate the middleware order, using the MapController method, it already find the endpoint and return the response, so it will not invoke the next middleware.
You can refer the following code: in this sample, by using the MapControllser method, it can't match the /map1, so we can access it using https://localhost:44379/map1 (change the port to yours).
The result like this:
More detail information, see ASP.NET Core Middleware.

HttpModule based plugin migration to .net core

I have a .net framework 4.7 project which is essentially an HTTPmodule to be used independantly in IIS server to detect incoming requests and responses, to 3rd party applications installed in IIS,which then need to be modified.
We were adding the module using the webconfig for the respective applications.However now i am migrating it to .net core 6.we use a sample web api to test the httpmodule project.However it seems the addition has to be in startup.cs of the sample web app.
Issue:-
1.I add a middlware to the 1st project like below
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace Myspace.HttpModule.Example
{
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
return _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class MyMiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
}
2.Now i need to add this to the 2nd project which is the sample web app to test the HTTPModule.However when i try to add it to the startup.cs file that i created in the sample web app project
using Myspace.HttpModule.Example;
using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.UseMiddleware<MyMiddleware>();
app.UseMyMiddleware();
app.MapControllers();
app.Run();
I get compilation errors at
app.UseMiddleware<MyMiddleware>();
app.UseMyMiddleware();
So is it that i cant add like this.Wouldnt "using" work in this case?
Also is this the only way to add a middleware to be able to get requests globally or from the specific sample or 3rd party app?
I googled a lot but couldn't find piece together a definite answer. I am a newbie to .Net
The error is like below
Update:-
The error image is
your screenshot is pointing to a spelling mistake. its UseMiddleware not Middelware as it can be seen in your screenshot.
please check if you are using correct name.
and also you only need to use either
app.UseMiddleware<MyMiddleware>();
or
app.UseMyMiddleware();
not both.
the method should be included in
namespace Microsoft.AspNetCore.Builder
assembly:Microsoft.AspNetCore.Http.Abstractions.dll
which was included in Microsoft.AspNetCore.app in your project when you created the project :
please check the framewok if there's something wrong with it

Call SignalR Hub From Another .Net Project

I've got SignalR hubs in one .NetCore project and SignalR clients in another .NetCore project (to comply with internal infrastructure guidelines). I'm struggling with how to implement the client code that will provide the connection to the hubs. All my projects build fine, I'm just missing the connectivity part.
Client Project:
public class MyClientController
{
private readonly IHubContext<MyHub, IMyHubClient> _hub;
public MyClientController(IHubContext<MyHub, IMyHubClient> hub)
{
_hub = hub;
// THIS NEVER GETS CALLED/HIT BECAUSE I DON'T KNOW HOW TO REGISTER IT
_hub.Clients.All.BroadcastMessage("Notify", $"Hello everyone. This has been constructed");
}
}
I'm guessing I need to do some configuration in the Startup.Configure() method? I've installed the client package already,
EDIT: I added the following code, but it's complaining about the format (remember, this is not a relative path, it's in another service).
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<MyHub>("http://localhost:60913/myHub");
}
Am I on the right path here?
The connection is made by mapping a route to your hub class. The docs have a good example. This includes:
// Add to services collection
services.AddSignalR();
// Map the route "/chathub" to a ChatHub class
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chathub");
});
By the way, a hub can be a standalone class not associated to a controller.

Solve json capitalization

When I access an ASP.NET web api using angular from the same web site, all the first letter lowercase, even if they aren't lowercase on the server.
However, if I move the API's to a different web site and enable CORS, I will receive the JSON exactly as the properties are written on the server.
Is there some way to control this difference? It becomes a mess when I need to move an API to a different web site
The default for serializing output to JSON has changed so you may encounter this issue when migrating .Net frameworks. You can read more about the issue here or here but to resolve you can specify the DefaultContractResolver.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
}
In your Owin Startup add this line...
public class Startup
{
public void Configuration(IAppBuilder app)
{
var webApiConfiguration = ConfigureWebApi();
app.UseWebApi(webApiConfiguration);
}
private HttpConfiguration ConfigureWebApi()
{
var config = new HttpConfiguration();
// ADD THIS LINE HERE AND DONE
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.MapHttpAttributeRoutes();
return config;
}
}
JSON is case sensitive as a rule JSON keys should have matching case. Some unix servers will ignore case sensitivity but I believe windows servers enforce it.
The error is in the naming conventions in the api or code requesting/processing those keys. Best to use lowercase keys using a under_score as the seperator instead of camelCasing.
http://jsonrpc.org/historical/json-rpc-1-1-alt.html#service-procedure-and-parameter-names
ref: When is case sensitivity important in JSON requests to ASP.NET web services (ASMX)?

how to get HttpContext.Current.GetOwinContext() in startup

I very read for this problem but i can not fixed this so i think create a new question in this site.
HttpContext.Current.GetOwinContext();
i want get GetOwinContext values with above code . above code there are in my startup.cs
[assembly: OwinStartupAttribute(typeof(OwinTest.Startup))]
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var c = HttpContext.Current.GetOwinContext();
}
}
and i get this error
//No owin.Environment item was found in the context
but var c = HttpContext.Current.GetOwinContext(); work for me in HomeController fine.!
I just get GetOwinContext in my startup.cs class.
thankfull
You can't do that. The OWIN context does not exist without a request, and the Startup class only runs once for the application, not for each request. Your Startup class should initialize your middleware and your application and the middleware and the application should access the OWIN context when needed.
As mentioned, what you are asking isn't possible. However, depending on your requirements, the following is possible and gives you access within the context of creating object instances. This is something I needed in order to check for whether an instance was already added else where (I have multiple startup classes in different projects).
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
// Ensure we have our "main" access setup
app.CreatePerOwinContext<DataAccessor>(
(options, owinContext) =>
{
// Check that an instance hasn't already been added to
// the OwinContext in another plugin
return owinContext.Get<DataAccessor>() ?? DataAccessor.CreateInstance(options, owinContext);
}
);
}
Within the CreatePerOwinContext we have access to the OwinContext, so we can access it at the point of creating a new type. This might not help everyone as it's a little more specific to a person's needs, but is useful to know.

Resources