Retrieve names of Online users connected to a Server - asp.net

I asked this question before which has got a very good response. But as I am new to asp.net (and jquery) cant understand how the program is flowing.
Summary:
I have created a Basic chat application. Now I am trying to add a advanced function like whenever a user is online (connected to a server), the server should show or broadcast the available online user's username to all the users connected to that server.
By referring the responses to the previous question (s0nica and VinayC), I modified my class file and jquery file, which are giving errors as shown in the below links. (I think I am very close)
Chat.cs (Two errors, I mentioned errors in between code comments)
file.js (Working fine, refer it if you need to)
Please have a look to the above files and assist me.
PS: In the previous post, I was thinking that if I change the Global.asax code, my problem will be solved.. which I realized later as wrong..

Your first error from:
Clients.joins(Context.ConnectionId, Caller.username, DateTime.Now);
Shold be:
Clients.All.joins(Context.ConnectionId, Clients.Caller.username, DateTime.Now);
Other errors associated with it: In your JS file it should be:
Line 15
chat.state.username = chatUsername;
Second error:
The error is exactly as it states, you do not have a toList function off of your dictionary object. Secondly you can't plainly convert a List or a string directly to a Chat object.
Based on your setup you currently dont have a proper "user" list to return. Right now you're saving a List to represent an individual user. You might want to try changing your dictionary object to be something like
static ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>();
Where User is:
public class User
{
public string Name { get; set; }
public string ConnectionID { get; set; }
}
Then on your Joined function you could just do:
public void Joined()
{
User user = new User
{
Name = Clients.Caller.username,
ConnectionID = Context.ConnectionId
};
_users.TryAdd(user.ConnectionID, user);
Clients.All.joins(user.ConnectionID, user.Name, DateTime.Now);
}
Lastly your GetConnectedUsers would end up(make sure you're 'using System.Linq;'):
public List<User> GetConnectedUsers()
{
return _users.Values.ToList();
}
I probably went a little bit overboard but hopefully this helps!
If you need a reference to the change log from SignalR 0.5.3 to 1.0 alpha here's a great post on all of the modifications:
http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx

Related

sending messages to single clients NOT identified by name (Identity)

I know similar questions have been asked before, but here goes
I have an ASP.NET app that serves images to connected clients. All clients are connected via owin with username and password and there could multiple clients connected with the same username and password. However, each client may need to be served with unique images. This means that I need to use a unique "hub ID" to serve each image.
The problem comes from retrieving this "hub ID" on the GetUserID method of the CustomUserProvider class. The IRequest parameter doesn't provide me with enough information to uniquely identify the connection. If I can get (which I can't (??)) to the Session state of the page then problem solved.
Has anyone got any ideas. I'm thinking of perhaps using the url - which I can make unique for each connection....
(Does anyone know how to get the original url of the page in the GetUserID)
I solved this as follows. I append a unique id on the URL. Then in the GetUserID of the CustomUserProvider
public string GetUserId(IRequest request)
{
string id = "";
try
{
HttpContextBase requestContext = request.Environment[typeof(HttpContextBase).FullName] as HttpContextBase;
string url = requestContext.Request.UrlReferrer.AbsoluteUri;
var parsedQuery = HttpUtility.ParseQueryString(url);
id = parsedQuery["HUBID"];
}
catch { }
return id;
This HUBID is the one referenced in the code behind:
var hubContext = GlobalHost.ConnectionManager.GetHubContext<Hubs.MimicHub>();
hubContext.Clients.User(HubID).addImage(MimicImage,
ImageWidth, ImageHeight
);
Every Signalr connection (client) will have its own ConnectionId.
You could use this ID to Identify the same user foreach connection.
You can receive this unique connectionId:
public override Task OnConnected()
{
var connectionId = Context.ConnectionId;
}
more info:
http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections
Please see amended question. There may have been a better one, but this works perfectly.

How to send templated emails?

How does one send a templated Postmark message on ASP.NET? I'd imagine it would be done in this way:
TemplatedPostmarkMessage message = new TemplatedPostmarkMessage
{
From = "demo#demo.com",
To = "someone#else.com",
TemplateId = 1738,
TemplateModel = some_passed_in_model
};
The question now arises, what exactly is TemplateModel? From the API on Postmark's site, it seems like a JSON object, but in the definition from the DLL, it's as follows:
public object TemplateModel { get; set; }
I tried creating my own object with variable names that correspond to those on the Postmark template, however that does not work (it just sends a blank template). Postmark also does not have any documentation on how to use TemplatedPostmarkMessage in ASP.NET yet.
We send a dictionary of <string, object>, I believe you can use more complex models but a dictionary will get the job done.

Using ASP.net membership to get aspnet_Users in silverlight

Hope somebody can help.
Have looked around on the net but cannot seem to solve (or understand) this.
I have tried the code posted at
http://blogs.msdn.com/b/kylemc/archive/2010/05/10/using-asp-net-membership-in-silverlight.aspx
(not going to repeat the class MembershipServiceUser here as it is quite long and can be seen on the mentioned page)
I have set up the domain service with the class and the code to return the users:
//[RequiresRole("Managers")]
public IEnumerable<MembershipServiceUser> GetAllUsers()
{
return Membership.GetAllUsers().Cast<MembershipUser>().Select(u => new MembershipServiceUser(u));
}
I took out the RequiresRole for testing.
What I seem to be a bit blonde about is the calling of the GetAllUsers() method.
In my code behind I am using:
MembershipDataContext context = new MembershipDataContext();
EntityQuery<MembershipServiceUser> users = context.GetAllUsersQuery();
I am not 100% sure if this is the correct way to use the method or if something else is wrong because
context.GetAllUsersQuery(); returns "Enumeration yielded no results"
One question is also in the code kylmc uses //RequiresRole("Admin")]. Is this a custom role created in the ASP.NET Configuration editor?
Looking at another tutorial regarding using the ASP.NET authentication service in Silverlight, I create a role called "Managers" and added the login user to that role.
Logging in using a user with role Managers doesn't help and results are still not yielded.
Any ideas I could possible look at?
Many thanks
Neill
There are two steps involved with querying.
Get a query object from the Domain Service context (synchronous).
Load the query from the Domain Service context (asynchronous).
Example:
public void Load()
{
// define the query
var query = context.GetAllUsersQuery();
// start running the query, and when the results return call
// OnGetAllUsersLoaded
context.Load(query, OnGetAllUsersLoaded, null);
}
public void OnGetAllUsersLoaded(LoadOperation op)
{
var results = op.Entities;
}

How to get HealthVault to work with multiple ApplicationID in same application

We may never know why Microsoft decided to limit developers by making HealthVault applications constrained to a single web/app.config entry for a HealthVault application. However I need to be able to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
I won’t go into the details of the reasoning behind 2 different HealthVault applications, but other than to say we need it to work. I still cannot login correctly with MSDN Forums (think infinite redirection sign in loop) so I am hoping for a post here that will help me.
I did contact a HealthVault developer on how to achieve this however the developer gave a suggestion that I don’t believe would be reliable (if I’m wrong let me know).
The developer’s suggestion was to do the following in code when you needed to connect to HealthVault, but prior to connecting:
ConfigurationSettings.AppSettings[“ApplicationId”] = “[YOUR APP ID]”;
The problem is that this is a static property and I do see this as an issue as our web application will have different users accessing both HealthVault applications at the same time.
Does anyone have any suggestions to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
There is a way to dynamically switch app ids on runtime. Both applications must be created, both certificates must be installed. Few things to keep in mind. For every authenticated connection, user will be granted a token (aka wctoken). This token is consumed when user is redirect back from Live ID (in case live id is used...) by your redirect.aspx page (assuming your redirect page inherits from HealthServiceActionPage.This means that everytime you switch applications, you must redirect user back to Live ID with new app id to receive new token.
Here is code sample that can be user to dynamically change settings:
public class ConfigurationManager : HealthWebApplicationConfiguration
{
private string appid;
public ConfigurationManager(string appid)
{
this.appid = appid;
}
public override Guid ApplicationId
{
get
{
return AppManager.Current.GetCurrentAppId(this.appid);
}
}
}
public class AppManager
{
private static readonly Object lck = new Object();
public Guid? App;
public static AppManager Current
{
get
{
AppManager mgr = null;
if (_current == null)
{
lock (lck)
{
mgr = new AppManager();
}
}
return mgr;
}
}
private static AppManager _current;
public Guid GetCurrentAppId(string id)
{
return new Guid(id);
}
}
Usage:
ConfigurationManager cm = new ConfigurationManager(your-app-id-here);
HealthWebApplicationConfiguration.Current = cm;

Dynamic list constraint on Alfresco

I'm trying to follow the examples provided in this post, to create a dynamic list constraint in Alfresco 3.3.
So, I've created my own class extending ListOfValuesConstraint:
public class MyConstraint extends ListOfValuesConstraint {
private static ServiceRegistry registry;
#Override
public void initialize() {
loadData();
}
#Override
public List getAllowedValues() {
//loadData();
return super.getAllowedValues();
}
#Override
public void setAllowedValues(List allowedValues) {
}
protected void loadData() {
List<String> values = new LinkedList<String>();
String query = "+TYPE:\"cm:category\" +#cm\\:description:\"" + tipo + "\"";
StoreRef storeRef = new StoreRef("workspace://SpacesStore");
ResultSet resultSet = registry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, query);
// ... values.add(data obtained using searchService and nodeService) ...
if (values.isEmpty()) {
values.add("-");
}
super.setAllowedValues(values);
}
}
ServiceRegistry reference is injected by Spring, and it's working fine. If I only call loadData() from initialize(), it executes the Lucene query, gets the data, and the dropdown displays it correctly. Only that it's not dynamic: data doesn't get refreshed unless I restart the Alfresco server.
getAllowedValues() is called each time the UI has to display a property having this constraint. The idea on the referred post is to call loadData() from getAllowedValues() too, so the values will be actually dynamic. But when I do this, I don't get any data. The Lucene query is the same, but returns 0 results, so my dropdown only displays -.
BTW, the query I'm doing is: +TYPE:"cm:category" +#cm\:description:"something here", and it's the same on each case. It works from initialize, but doesn't from getAllowedValues.
Any ideas on why is this happening, or how can I solve it?
Thanks
Edit: we upgraded to Alfresco 3.3.0g Community yesterday, but we're still having the same issues.
This dynamic-list-of-values-constraint is a bad idea and I tell you why:
The Alfresco repository should be in a valid state all the time. Your (dynamic) list of constraints will change (that's why you want it to be dynamic). Adding items would not be a problem, but editing and removing items are. If you would remove an item from your option-list, the nodes in the repository with this property value will be invalid.
You will not be able to fix this easily. The standard UI will fail on invalid-state-nodes. Simply editing this value and setting it to something valid will not work. You have been warned.
Because the default UI widget for a ListConstraint is a dropdown, not every dropdown should be a ListConstraint. ListConstraints are designed for something like a Status property: { Draft, Waiting Approval, Approved }. Not for a list of customer-names.
I have seen this same topic come up again and again over the last few years. What you actually want is let the user choose a value from a dynamic list of options (combo box). This is a UI problem, not a dictionary-model-issue. You should setup something like this with the web-config-context.xml (Alfresco web UI) or in Alfresco Share. The last one is more flexible and I would recommend taking that path.

Resources