How can a client send a value to the server using SignalR and the server will update the model?
If I want to update my model / DB using SignalR, how is this achieved? (The other path, i.e. from server to client, is explained in many tutorials, but so?)
Let's say we have a simple model
public class User
{
public int UserID { get; set; }
public string UserName { get; set; }
}
And the corresponding form is the input field for the name. The hub is like
public class UserHub : Hub
{
public void UpdateName(string value)
{
// now what?
Clients.All.updateTheViewIfNecessary(string newValue);
}
}
Edit How to update the model i.e. How to achieve the same result as in normal CRUD edit controller
db.Entry(user).State = EntityState.Modified; db.SaveChanges();
source to share
For the purposes of this example, we will use a JS client to submit the model to the hub and link to the official documentation at
ASP.NET SignalR APIs Guide - JavaScript Client: How to Call Server Methods from a Client
Suppose a custom hub on the server
public interface IUserService {
bool UpdateName(string userName);
// Other methods not shown.
}
public class UserHub : Hub {
private readonly IUserService service;
public UserHob(IUserService service) {
this.service = service;
}
public void UpdateName(string value) {
if(value != null) {
var newValue = value;
if(service.UpdateName(newValue) == true) {
Clients.All.updateTheViewIfNecessary(newValue);
}
}
}
}
See Help Documentation Dependency Injection in SignalR to understand how to inject dependencies into a hub. In the above UserHub
, when a message is received, it uses the data in the model to update / save the data through the injected dependency and notifies clients based on the result of this operation. This can allow lengthy processes that can subsequently update clients as needed.
The JavaScript client code that calls the server method (presumably a generated proxy) would look something like this.
//This assumes View has an input field for the name
var message = "Test Name";
userHubProxy.server.updateName(message).done(function () {
console.log ('Invocation of UpdateName succeeded');
}).fail(function (error) {
console.log('Invocation of UpdateName failed. Error: ' + error);
});
The framework will handle any model bindings that need to be done on the server.
The actual hub acts as the endpoint of the service and sends the service invocation response to all its associated clients.
source to share
Call the server function to pass the values as shown in the javascript below.
I also have a sample html table containing a list of users to call a server function against each button.
<table id="tblData">
<tr>
<td><input type="button" value="User 1" /> </td>
<td><button type="button" value="2" title="User 2">User 2</button></td>
<td><input type="button" value="User 3" /></td>
<td><input type="button" value="User 4" /></td>
</tr>
</table>
var userId, userName, strOtherVal;
userId = 1; // sample values
userName = 'ali';
strOtherVal = 'admin';
$(function () {
$("#tblData tr td button,input").click(function (event) {
myHub.server.sendData(userId, userName, strOtherVal)
.fail(function (error) {
console.log('error sending data: ' + error)
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
On the server side, your function will look like this:
public void sendData(int userId, string userName, string strOtherVal)
{
//create model
var UserModel = new User() { UserID = userId, UserName = userName, OtherVal = strOtherVal };
//here call your function to check or post this model to db
}
public class User
{
public int UserID { get; set; }
public string UserName { get; set; }
public string OtherVal { get; set; }
}
source to share