Using Lambda expression to compare User Id (MVC 5, Identity) - c#

I have stored the user profile in another table, called Agent. The Agent table does not contain any navigation property since i couldn't find a way to store user id in the Agents table( in the examples from msdn, even they didn't do it).
An Agent has many packages, and now i have a create packages view. I wanted to store the logged in Agent's ID to get stored in the Packages. So in the package controller in the Post Create actionResult, i'm doing something like this:
var user = adb.Users.Where(p => p.Id == User.Identity.GetUserId()).Single();
var agent = db.Agents.Where(p => p.ID == user.Agent.ID).Single();
(I have 2 datacontext, one from the application user, and one i got from datafirst EF, i tried merging them, but i got errors.)
I am getting errors.
System.InvalidOperationException

The Enumerable.Single returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence. It throws InvalidOperationException , because the input sequence contains more than one element OR the input sequence is empty.

Instead of using Enumerable.Single, I would recommend using SingleOrDefault. This method returns null if there are no elements in the Enumerable rather than InvalidOperationException. You can then check for null value and take appropriate action if there is no entry in the Enumerable.
Ref https://msdn.microsoft.com/en-us/library/vstudio/bb342451(v=vs.100).aspx

I think the problem is in tables data (Users, Agents).
If you search by Id, I hope it's a key for tables, so I decided that you didn't add same records in one table, so we can remove variant that there are duplicates. If you use User.Identity.GetUserId() it's give background for decide that your user account already exist and the data in Users table is normal. InvalidOperationException in those places you can get if there are duplicates or data not exist. Variants with duplicates is left and I hope you use ID like key for table, so your problem is: You haven't any users in Agent table with ID which you get from user.Agent.ID. Two ways: wrong data in Agent or you get incorrect Id from user.Agent.ID(maybe problem in mapping). Try to create new User and new Agent for him and run your code. Are you sure that for all users should be an agent?

Related

Elasticsearch NEST Indeces and Indexing

my following problem is, that I have a List of Items and want to index those with elasticsearch. I have a running elasticsearch instance, and this instance has an index called "default".
So I'm running following code:
var items = GetAListOfItem();
var response = Client.IndexMany(items);
I also tried it with Client.IndexManyAsync(items). But that didn't do anything.
Only 1 Item of this List gets indexed. Nothing more. I think its the last item, which got indexed.
I thought it could be a thing with IEnumerable and multiple enumerations, but i parsed it as a List<Item>.
Another Question would be about the best practice with Elasticsearch. Is it common to use a Index per Model. So if I'm gathering data from for example Exchange and another system, I would do 2 indeces?
ExchangeIndex
OtherSystemIndex
Thank you for your help.
Update: I saw that my Client.Index does all those calls succesful, but all those objects got the same ID from NEST. Normally she had to increment by herself, isnt it?
Update 2: I fixed the Indexing Problem. I had setup an empty ID-Field.
But still have the question mit best practive about Elasticsearch.
If you are uploading all the data with the same id, it will not increment the id, that will update the record with that id and you will have only one record, so you can upload the data without an id or give wherever unique id to identified the records.
The other common problem is that your records have not the same mapping that you give for the index.
About the other question, in the indexes, you store the information that is relevant for you, even if that have content from many models, the only thing that you have to avoid is mix information, if you have an index about server logs dont mix it with user activities for example.

Run User Compare with ERPConnect (Theobald)

I would like to know if anyone knows if it is possible to run a SAP User Compare from c# using ERPConnect 4 from Theobald? If so, how?
I can open a connection to SAP and run functions - just don't know how to do User Compare.
EDIT:
It seems like we have to run the report PFCG_TIME_DEPENDENCY.
If anyone knows how to run a report with ERPConnect, or if there exists a functional module in SAP that can run a report, that will also help.
I am not exactly sure what your comparison has to include, but I assume, that you want to compare attributes of the users. If that is the case, you could download the users data from the SAP tables. Here is a starting point for what tables you probably need: http://www.tcodesearch.com/sap-tables/detail?id=USR01
USER01 is the user master record, containing all user with it's main attributes. You can find other interesting related user table through the link above.
To read a table using Erpconnect, look at this link: https://my.theobald-software.com/index.php?/Knowledgebase/Article/View/21/23/reading-sap-tables-directly
You need to create an instance of the ReadTable class. Then you add the fields you are interested in using the AddField method (e.g. MANDT and BNAME for the USR01 table). You could but don't have to enter filter criteria using the AddCriteria method. If you do add multiple creteria, be sure to add boolean operators like "and" or "or":
table.AddCriteria("LANGU = 'D'");
table.AddCriteria("AND MANDT = '007'");
Finally set the table name of the table you want to download and execute the Run-Method. After that you can loop through the results stored in <your RunTable-Instance>.Result.Rows
Sascha

Get all roles of any user (yes, not currently logged one)

In an MVC app, administrator has a CRUD controller for managing users. Now, the functionality of the edit part needs to be extended and it involves adding a number role dependent tabs. They depend on the role of the viewed user, rather than on roles of the administrator who is viewing them. The easiest way for achieving this, would be getting all roles of that user as a array of strings (or similar), but how do I actually go about obtain those.
Is there a preferred method of getting all roles of a single user in SimpleMembership (based on his UserId) or do I just have to patch up a stored function in the database and pull those through it?
Writing the function is not a big deal, but this problem doesn't sound like something I should have to make workarounds for.
Use the Roles.GetRolesForUser() method https://msdn.microsoft.com/en-us/library/8h930x07(v=vs.110).aspx
string[] rolesArray = Roles.GetRolesForUser("username");
With the string being the User Name of the user as contained in the aspnetdb.
If you want to find by using a guid, you could try the following:
Guid userId; // ID of user - you can populate this somehow
MembershipUser memUser = Membership.GetUser(userId);
string[] roles = Roles.GetRolesForUser(memUser.UserName);
Here is the stored procedure I mentioned in the question:
CREATE FUNCTION GetUserRoles
(
#UserId int
)
RETURNS TABLE
AS
RETURN
(
SELECT
r.RoleName
FROM
dbo.webpages_UsersInRoles uir
JOIN dbo.webpages_Roles r ON (r.RoleId = uir.RoleId)
WHERE
uir.UserId = #UserId
)
GO
The only reason to go with this instead than the answer by user1666620, would be if you wanted to skip one unnecessary query to the DB. The preferred method to use this solution would be to add this function to your dbml (or it's EF equivalent). Obviously this first needs to be added in the database.

Maker-Checker functionality for asp.net

I'm creating a maker-checker functionality where, maker creates a record and it is reviewed by the checker. The record creation will not happen until the checker approves it. If the checker rejects it then it should be rolled back.
The idea which i know is create a temporary table of records which will hold the records to be created until the checker approves it. But this method will have 2X number of tables to be created to cover all functionalities.
What are the best practices to achieve this?
Is it something which can be done using Windows Work Flow.? (WWF)
Just add a few more columns to your db.
Status : Current status of record ( Waiting for approval, Approved,
Declined . etc)
Maker : Username or id
Checker : Username or id
Checker Approval/Rejection Time
Alternatively if you have lots of tables like this needs to maker/checker workflow you can add another table and reference all other record to this table.
Windows workflow foundation also could work for you but i persnoally find it difficult to use
If you want revisions for the recored you also need more columns. Such as Revision Number and IsLastRevision.
I dont know what you are using for accessing db and modifiying records. If you are using OR/M you might override Update and do revisions on all saves . For Example
void Update(Entity e )
{
Entity n = new Entity();
// Create a copy of e ( With AutoMapper for example or manually )
e.Current = true;
e.RevisionNumber += 1;
Update(e);
Insert(n);
}
In this case you will have two options:
Create two identical tables and use one table for approved data and one for requested data.
OR
You can create two rows for a user with TypeID(requested/approved). in this case user will create a request with typeID = requested when approver approved that request you simply override current approved record with new one otherwise simply mark requested row with rejected status.

Website database duplicate records

On every page of my website a token is passed in as a querystring parameter. The server-side code checks to see if the token already exists in the database. (The token is a uniqueidentifider field in the database). If the token exists then it will use the existing one, if not then it will create a new row with the new token.
The problem is once in a while I see a duplicate record in the database (two rows with the same uniqueidentifider). I have noticed the record insertion times were about half a second apart. My only guess is when the site is being visited for the first time the aspx pages weren't fully compiled. So it takes a few seconds and the user goes to another page of the site by typing in a different url and the two requests were executed almost at the same time.
Is there a way to prevent this duplicate record problem from happening? (on the server-side or in the database??...)
This is the code in questions that's part of every page of the website.
var record = (from x in db.Items
where x.Token == token
select x).FirstOrDefault();
if (record == null)
{
var x = new Item();
x.Id = Guid.NewGuid();
x.Token = token;
db.Items.InsertOnSubmit(x)
db.SubmitChanges;
}
Yes, create a unique index on your token field.
create unique index tab_token on your_table(token);
This way, database will make sure you will never store two records with the same token value. Keep in mind that your code might fail when running this due to the index constraint, so make sure you are catching that exception in your code and treat it accordingly.
What is probably happening is that two request are being served at the exact same time and some racing conditions are causing two tokens getting the same value. It would help to identify your problem if you post some code.

Categories

Resources