Online chat solution for Asp.Net MVC 5.1 website - c#

I have an Asp.Net MVC 5.1 website. We've got 3 types of users and I want to add support for chat between one type of them. I have thought of some models like this:
public class Conversation
{
public NormalUser A { get; set; }
public NormalUser B { get; set; }
public List<PrivateMessaage> Messages { get; set; }
}
public class PrivateMessaage
{
public NormalUser Sender { get; set; }
public NormalUser Receiver { get; set; }
public string Message { get; set; }
public DateTime Created { get; set; }
}
Also, I'm using SignalR in other parts of the project and thought like it's a very good solution to add the chat interface on top of the SignalR. Everything looks good so far. However, I think hitting the database to insert a new message EVERY time a message is being typed is not a good idea. I've created so many strategies to implement custom donut caching in my website to make every single page as fast as possible and it seems like this would cancel all of them out! What is the preferred solution to this problem? I think I might take some approaches like these:
Push them to the database in batches. For instance once a message is past a threshold (its date/time difference is more than X or the message count is more than Y).
Don't support offline messages, just push them in-memory to the other side through SignalR.
Same as the 2nd, but support offline when the target user is offline. I imagine not many messages will be sent to offline users!
Don't cache anything. I'll work out!!
One issue with the first one is that, there might be a situation where the website would go down (for update, power failure, apocalypse(!), etc.) and all the messages in memory would be lost. I can add a custom action to flush everything but it's never quite safe. Since there's a lot of chat solutions out there, I think there are very convenient solutions to this.

If you are not opposed to using other databases, realtime chat is extremely easy using Firebase and AngularJS.

Related

Blazor save basic filter data to browser when reloading page

How can I save data from a object to the browser and retrieve that data using server-side Blazor?
I have a model to filter an overview, but if you navigate away from the overview and come back the filter is gone. It's a pretty advanced filter so filling it out every time is not really an option.
Let's do this simplified example:
public class OverviewFilterModel
{
public string Keywords { get; set; }
public int PartnerId { get; set; }
public EnumStatus Status { get; set; }
}
public enum EnumStatus
{
A,
B,
C
}
How do I save above model in browser and retrieve it again? Or is there no such thing? I do not want to use an SQL database for this, or anything server-side.
You can use Blazored.LocalStorage. Its a third party library developed by Chris Sainty to store data in your browser which persists across pages and you can access that data from a new tab as well.
Just pull the library from Nuget, register the service in your Startup class, inject it into any page or component you want and then store whatever data you want in the browser local storage.
#inject Blazored.LocalStorage.ILocalStorageService localStorage
#code {
protected override async Task OnInitializedAsync()
{
await localStorage.SetItemAsync("name", "John Smith");
var name = await localStorage.GetItemAsync<string>("name");
}
}
You can add complex nested objects as well.
You can verify the data/model that you have stored in your browser local storage if you open developer options.
Here's the github repo link. You will find all the documentation here :
https://github.com/Blazored/LocalStorage

C# - Send a WinForm over TCP

I have created a client server application which is currently able to send messages as containers:
[Serializable]
public class MsgContainer
{
public string TableName { get; set; }
public bool SomethingBool { get; set; }
public DataTable DataTableData { get; set; }
}
The problem: Depending on the request from the user I would like the server to be able to send Forms
public Form requestedForm { get; set; }
The problem with that (as i have read in the web and tried in my application) WinForms are not serializable which is why i receive the following error:
System.Runtime.Serialization.SerializationException: 'Type 'System.Windows.Forms.Form' in Assembly 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.'
Is there any workaround to my problem?
I would strongly advise you find a different approach to whatever you're trying to do. The Form is not serializable. You could:
Make a serializable class to transfer all the form information and regenerate a form based on it.
Write your own serializer and deserializer for a form.
Either way you would need to overcome the many following issues, such as:
Components in the form are also not serializable.
Each control may have a value or a binding to a data source that also needs to be transferred.
You can include infinite different objects and classes in a form that would be part of your main project. Everything would need to be in a library consumed by both server and client.
Basically, this would be your worst nightmare and after spending however much time you may spend working on it, you will eventually realise that you have nothing but bin filler.
You cannot (reasonably) serialise a form.
A better approach, if viable, would be to build the forms into the client app. Then have the server instruct the client as to which form to open. Optionally use an enum for this.
public enum FormType
{
Products,
Customers
}
public FormType RequestedForm { get; set; }
Sending a Form is a pretty pointless excersise. Forms are just there to Display data. If you want a certain form to be dispalyed, send the Data it needs rather then the whole Form.
Honestly it sounds like you either have some very faulty design. Or wanted to do a WebApplication the whole time. Consider that you might be stuck in a XY Problem.

Polymorphism + DDD

In my first project going real DDD, I'm stuck with some doubts concerning which course to take in this scenario...
I have a distributed architecture, in which users of several applications will have only one account that will make them able to authenticate. This account can be created on our own system, or the user can share with us his login with facebook, google and other third-party account provider.
So, there's a project for only this purpose, control user accounts.
This scenario made me came with this approach within my model (simplified):
public class User
{
public User(string name)
{
Id = Guid.NewGuid();
Name = name;
}
public Guid Id { get; protected set; }
public string Name { get; protected set; }
}
public abstract class Account
{
protected Account(User user)
{
Id = Guid.NewGuid();
User = user;
}
public Guid Id { get; protected set; }
public User User { get; protected set; }
}
public class MySystemAccount : Account
{
public MySystemAccount(string email, string password, User user)
: base(user)
{
Email = email;
Password = password;
}
public string Email { get; protected set; }
public string Password { get; protected set; }
}
public class FacebookAccount : Account
{
public FacebookAccount(string facebookId, User user)
: base(user)
{
FacebookId = facebookId;
}
public string FacebookId { get; protected set; }
}
The thing is that the other applications will access this project via REST services.
So, I thought about a single /Authenticate service that will provide a json with dynamic form. It could de a json with a email/password, or a json with the facebookId.
But then, how can I connect the layers?
I thought about making an application service, but I got stuck on who and how should decide what is going on, what should my rest service communicate to the application and how the application will know to do the thing, whatever kind of authentication it is, an user from my own domain or a user from facebook and so on..
Any thoughts on this?
Thanks!
This seems to be a multi-part question - one part about the object model and polymorphism and another about architecture.
Regarding the object model, the use of inheritance isn't ideal in this scenario. Each sub-type of Account won't really have much specific behavior or any behavior at all. The only specialization is the presence of different data fields. Additionally, use of inheritance will complicate persistence.
Architecturally, what I think you're trying to achieve is federated identity. This basically decouples the notion of a user (an identity) from the authentication process. In turn, this allows all remaining application code to bypass authentication concerns and depend only on the user's identity. Take a look at OpenID as well as the DotNetOpenAuth library which provides an OpenID implementation in C#.
I'm new to Stackoverflow, so not sure how to just put this as a "suggestion", but I would rethink your model a little bit. I think of a "User" as someone who strictly is a person utilizing your application through your own website. This "User" would go through the authentication as you suggested, either via an account from your own system, or via an Open ID or OAuth ID provider like Facebook and Google.
If an application however, wants to access your "application" via REST calls, then I'd put them through a different authentication mechanism. In a sense to me, you are providing an API layer and software as a service. I'd take a look at how Twitter, Facebook, or Google expose their APIs for other applications to use. Typically, there is a secret key and application ID involved in authenticating the REST calls.

SharePoint WebPart Custom Settings - Best Practise

I'm trying to ascertain what the best practise is for creating a SharePoint WebPart that has custom properties. I'll detail the background, because I might be doing this in completely the wrong way.
I've taken a DevExpress chart, which has a whole host of settings on there. I then decided to expose some of these settings and ended up with a WebPart that looked like:
public class MyWebPart : WebPart
{
public DataTable { get; set; }
public String ConnectionString { get; set; }
public String Query { get; set; }
public override void DataBind()
{
UpdateMyTable(ConnectionString, Query);
this.chartControl.DataSource = this.DataTable;
}
}
I needed to add a whole load more settings onto this web part, a few single items that are strings, and others that correspond to a series (e.g. Binding values, Chart Type). So I moved the settings off the WebPart and ended up with something more akin to the following:
public class MyWebPart : WebPart
{
public DataTable { get; set; }
public ChartSettings { get; set; }
public override void DataBind()
{
UpdateMyTable(ConnectionString, Query);
this.chartControl.DataSource = this.DataTable;
}
}
public ChartSettings
{
public List<SeriesSettings> Series { get; set; }
}
I made my settings classes Serializable and added a Personalizable attribute on the Property on my web part. This works fine via the web.
If I attempt to open the page in SharePoint designer however it complains that it can't create a ChartSettings (and DataTable) from their String representations. I've learnt that this is because the settings are exposed as Strings. Obviously the DataTable I can suppress the serialization of.
My question ultimately is, am I following the correct approach, moving settings onto a class? Or should I be leaving all the settings on my webpart (which would be messy keeping lots of series settings in different arrays), or is there a completely different approach? If you can point me to any references to support your suggestion (e.g. MSDN) then that would be very much appreciated.
My personal experience (and some may disagree) has been to keep the WebPart as thin as possible. WebParts seem to be awkward for things like: configuration, error handling and logging, tracing, etc. I have found it much easier to put the bulk of my development into a WS (WebService/WCF) on localhost:8080. The code in the webpart is simple: call the WS and let it do all of the work. Config in the webpart is now simple because localhost is always easy to find. Dev tools for WS/WCF are very strong. Config, debugging, error handling, logging, tracing are all much simpler in WS/WCF. Better still, I make a simple jig (Winform/Webform) to call/test my WS layer. With this architecture, you put your code where your dev tools are strongest. It is similar to the rationale behind the MVC pattern.

MVC C# Web application

How do I edit information from an customer settings data model, which doesn't come from a database.
I've created a view which starts with
edit.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
Notice it contains MyApp.Models.LocationDisplayOptions. How can I save data on the form, which isn't linked to a database. I'm sorry if this isn't clear, but simply I need to save data not stored in a database.
namespace MyApp.Models
{
public class LocationDisplayOptions
{
public string Town { get; set; }
public string Country { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public LocationDisplayOptions()
{
// Some web url stuff
Town = dt.Rows[0]["City"].ToString();
Country = dt.Rows[0]["CountryCode"].ToString();
Latitude = System.Convert.ToDouble(dt.Rows[0]["Latitude"].ToString());
Longitude = System.Convert.ToDouble(dt.Rows[0]["Longitude"].ToString());
}
}
}
Why do you need to save it? What are you going to do with the data after you save it. That's going to really drive the answer.
If you just need to persist information from one view of the page to another, you can put it in a Session variable.
If you need to persist it longer than that, you could store it in a file on the web server, but if it is a high volume website, that can really slow things down.
You could consider a database. Microsoft SQL CE is a good option for small-footprint data stores, as it doesn't require any server-side installs-- just a DLL that goes along with the rest of your application.
Here's a link to ScottGu's post about SQL CE: http://weblogs.asp.net/scottgu/archive/2010/06/30/new-embedded-database-support-with-asp-net.aspx
Do you merely used drag and drop to work with databases, letting magic happen as far as editing of data is concerned?
While you can exist with LINQ to SQL or EF drag and drop, the "magic" underneath the hood is worthwhile to learn, especially in light of other forms of persistant mechanisms.
To persist to a file, you have to capture the form data and then create a class that handles the save to the file. The best path is to Google saving to the type of file (comma separated, XML, etc) and create the software to handle the persistance of that information. You can test it with a simple console app. When you are happy, use the same pattern to wire to your MVC application. The main difference is you have to get the path from the ASP.NET internals (hard coded == bad).
Someone may have an open source "module" that does this work, so search the open source sites.
Peace and Grace,
Greg
Twitter: #gbworld
Blog: http://gregorybeamer.wordpress.com

Categories

Resources