J
J
Jaguar_sea2014-08-05 07:40:12
SQL
Jaguar_sea, 2014-08-05 07:40:12

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.

Can you share a link to the manual for this solution?

We automatically get a multi-user application, you can connect as many WPF clients as you like to the web service.

If I understand correctly, you need to use a framework for these purposes. Tell me the framework in a simpler way, for a beginner.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Entelis, 2014-08-05
@DmitriyEntelis

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='Роли пользователей';

Roles are combined into groups (administrators, moderators, etc.)
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='Связь групп и ролей';

Well, users are tied to groups
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='Связь пользователей и групп'

2) When a user logs in, we get a list of his roles
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

3) Within the framework of this example, it is assumed that all roles are exclusively "permissive". If the user has a role, he can perform the corresponding action. No, he can not.
Accordingly, in the application logic, when a user tries to perform some action, we simply check if he has a role.
Phew)
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 last coded under the desktop about 12 years ago in Visual Basic (not yet .net), but nevertheless:
You must have the code that creates this menu. Insert all role checks into this code.
If there is no menu code (you have assembled the menu through the constructor), then you need to write code that is executed, say, when the form is loaded, looks at the roles of the current user and, accordingly, turns on / off the menu items.

O
Ogoun Er, 2014-08-05
@Ogoun

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();
        }
    }

Actually everything. The comment above shows examples for working with the database. The use of frameworks is inappropriate here, there are few tables, it will be easier to manually map onto objects.
We get the following diagram:
29347e299155457794990fe5883ba88a.png

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question