Answer the question
In order to leave comments, you need to log in
What to read about how to create a multi-user WPF C# program?
I want to write a WPF C# SQL Server client/server application. Unfortunately, I have absolutely no experience in this part, so I came across a rake.
So, to the program... A user with administrator rights must register new users and grant them access rights to the functional part of the program (add, read, edit, delete). I can not find at least approximately similar database architecture. It is also not clear how in this part the database should interact with various program controls. Please, tell me some article-an example on this issue.
Interaction with the database goes through a web service, and the WPF application does not know about the database at all, working with the model.
We automatically get a multi-user application, you can connect as many WPF clients as you like to the web service.
Answer the question
In order to leave comments, you need to log in
I will share a ready-made example
1) It is necessary to somehow store user rights in the database. We introduce the
concept of "role" - this is some trivial access right to a specific section (for example, user_view, user_edit, user_delete).
CREATE TABLE `role` (
`role_title` varchar(255) NOT NULL COMMENT 'Роль',
`role_title_description` text NOT NULL COMMENT 'Описание роли',
PRIMARY KEY (`role_title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Роли пользователей';
CREATE TABLE `group` (
`group_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID группы',
`name` text NOT NULL COMMENT 'Имя группы',
PRIMARY KEY (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Группы пользователей';
CREATE TABLE `xref_group_role` (
`group_id` int(11) NOT NULL,
`role_title` varchar(255) NOT NULL,
PRIMARY KEY (`group_id`,`role_title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Связь групп и ролей';
CREATE TABLE `xref_user_group` (
`user_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`group_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Связь пользователей и групп'
SELECT
distinct `role`.`role_title`
FROM
`xref_user_group`
JOIN `xref_group_role`
ON `xref_user_group`.`group_id` = `xref_group_role`.`group_id`
JOIN `role`
ON `xref_group_role`.`role_title` = `role`.`role_title`
WHERE
`xref_user_group`.`user_id` = 123
Thank you very much!
Only it is not entirely clear how this should interact, for example, with the menu. For example, there is a menu Edit -> Add, Edit, Delete. If the user has the rights to add and modify but not to delete, how can I make the "Delete" menu item not active?
I will not write about the base. but about the general part. Here it would be nice to separate the application, UI (WPF application), web service, and database into layers. Accordingly, all interaction with the database goes through a web service, and the WPF application does not know about the database at all, working with the model. At the level of the web service, authorization is implemented, and a set of operations available to the user is determined (for example, the admin can do everything, the operator can only call read operations). We automatically get a multi-user application, you can connect as many WPF clients as you like to the web service. (respectively, not only WPF if necessary).
In one of my implementations, where the data set was limited to 100 megabytes, I generally used SQL Compact Edition, writing (a rare operation in the project) was carried out to the database, when the web service was started, all data was placed in RAM from the database and when reading data to The disk has not been accessed.
Creating a Web Service
Another Example
Creating a Proxy for a Web Service
Although I like to make proxies manually, more flexibility:
[WebServiceBinding(Namespace = "SampleWebService")]
public class SampleWebServiceProxy : SoapHttpClientProtocol
{
public SampleWebServiceProxy(string serviceUrl)
{
Url = serviceUrl;
UseDefaultCredentials = true;
}
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest webRequest = base.GetWebRequest(uri);
((HttpWebRequest)webRequest).ServicePoint.ConnectionLeaseTimeout = 0;
return webRequest;
}
[SoapDocumentMethod("GetUser",
Action = "http://domain/GetUser",
Use = System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Wrapped)]
[WebMethod(MessageName = "", Description = "")]
public User GetUser(Guid id)
{
return InvokeMethodWithResult("GetUser", id);
}
[SoapDocumentMethod("UpdateUser",
Action = "http://domain/UpdateUser",
Use = System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Wrapped)]
[WebMethod(MessageName = "", Description = "")]
public void UpdateUser(User user)
{
return InvokeMethod("UpdateUser", user);
}
private object InvokeMethodWithResult(string methodName, params object[] args)
{
return Invoke(methodName, args ?? new object[] { }).FirstOrDefault();
}
private void InvokeMethod(string methodName, params object[] args)
{
Invoke(methodName, args ?? new object[] { }).FirstOrDefault();
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question