Defaulting logged username and current timestamp in forms

#1

I am new to RADZEN and recently bought the professional licence to learn the tool. For each new record, I need to store the user who created the record as CREATE_BY and also current timestamp as the CREATE_DATE. How to default these values from form? Thanks

1 Like

#2

Hi @rmunian,

You can use the approach described here:

For current date you can use new Date() client-side and DateTime.Now() server-side.

Best Regards,
Vladimir

1 Like

#3

Hey @enchev, could you explain a little bit more about this?

I believe I am trying to the same thing as the OP, create a Field in a Form that will log the date and time of when the Form was Submitted and write that timestamp into the database.

I tried adding {DateTime.Now()}, ${ DateTime.Now()}, or DateTime.Now() into the DefaultValue of a Field in a Form and either got nothing or something like “NanNaNNaN”

Thanks so much!
Chadrick

0 Likes

#4

Hi @Chadrick,

You can use ${new Date()} client-side (JavaScript in the Angular app) as expression. DateTime.Now() can be used in the server-side app (.NET Core with C#/VB.NET)

Best Regards,
Vladimir

0 Likes

#5

That makes perfect sense. Thanks again!

0 Likes

#6

I tried adding ${new Date()} as the DefaultValue to a field with Date property in a Form but it does not want to seem to work.

0 Likes

#7

Hi @Chadrick,

Form DefaultValue is a bit different since it is serialized in the HTML and not as TypeScript code. In this case you can create a property (on page load) with the current date expression (${new Date()}) and bind the DefaultValue to this property.

Best Regards,
Vladimir

1 Like

#8

@enchev,

Awesome that worked! Thanks so much! :grin:

0 Likes

#9

Thanks for contributing to this post. However, I have an comment to pass. Doing CRUD operation on almost most systems I have worked in my last 24 years in IT, 99.999% of the time we need to capture the userID, date/time the record is created or updated or other DML statements. I would think this is an obvious default feature that should be provided. We as developers servicing the business, should be concentrating more on delivering the complex business requirements rather than coding the obvious stuffs that define the metadata of a transaction. Maybe I am wrong here. Still find the tool is great and definitely worth it :slight_smile:

Great job and thanks again.

1 Like

#10

@rmunian thank you for the feedback! How is this handled in other systems you have worked with? I mean passing the user id and date time? We would really like to improve that.

0 Likes

#11

Hi Korchev, I am not sure if my answer will help but I give it a go. I would say that once a user is logged on and authenticated, an instance of a top level class should hold the session details - like userId logged on, the workstation details, and other methods that allow the user to retrieve the current timestamp. One useful info also is the ability to return the name of the form (like a form ID) that processed the transaction. Basically, those information are then inserted in the data entry forms as parameter values in the DefaultValue property. For example, I use DataStage a lot in my current job and whenever I need, for example, get the name of a project I call $ProjectName() and it returns me the project name value, $JobName() and it returns the job name value, CurrentTimestamp() and returns me the currentdate and time at runtime, etc…

Note: I am an OLAP developer and not an OLTP developer. However, these metadata are crucial for my work in ETL’ing, mining, reporting and analysis. You would know better how to implement those features in a front-end application.

Hope I help a little bit.

1 Like

#12

A bit different but same concept:

In an application I'm working on we need to populate in every record saved "CreatedAt", "CreatedBy", "ModifiedAt", "ModifiedBy" fields to audit purposes. Datetime fields can be populated with triggers in database but username fields need to be populated in the app. Would be nice if we can hook in some way with a generic onCreated and onModified custom partial class. It's possible with Radzen?

Thanks,

0 Likes

#13

Check this post.

0 Likes

#14

Great!

Thanks a lot.

0 Likes

#15

Hi,

I'm trying to follow Audit sample and all work fine but, when I tried to get current username on SaveChanges override with
var userName = httpAccessor.HttpContext.User.FindFirst(ClaimTypes.Name).Value;
an exception is thrown.
I use active directory for security and authorization.

Thanks in advance for your assistance.

0 Likes

#16

What is the exception?

0 Likes

#17

If I add this code to OnConfigureServices

var policy = new AuthorizationPolicyBuilder()
{
AuthenticationSchemes = new [] {"Bearer"}
}
.RequireAuthenticatedUser()
.Build();

        services.AddMvc(options =>
        {
            options.Filters.Add(new AuthorizeFilter(policy));
        });

when I tried to login the exception is:

dotnet: fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0]
An unhandled exception has occurred while executing the request
System.InvalidOperationException: No authentication handler is configured to authenticate for the scheme: Bearer
at Microsoft.AspNetCore.Authentication.AuthenticationService.d__10.MoveNext()

If I don't add it, I can log in but exception is thrown in Audit method

dotnet: Object reference not set to an instance of an object.

0 Likes

#18

Indeed the Bearer policy isn't registered now when Active Directory security is used. We will have to fix that. In the mean time you can register it manually in Startup.Audit.cs (you will have to import a few namespaces)

partial void OnConfigureServices(IServiceCollection services)
{
    var tokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = TokenProviderOptions.Key,
        ValidateIssuer = true,
        ValidIssuer = TokenProviderOptions.Issuer,
        ValidateAudience = true,
        ValidAudience = TokenProviderOptions.Audience,
        ValidateLifetime = true,
        ClockSkew = TimeSpan.Zero
    };

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(options =>
    {
        options.Audience = TokenProviderOptions.Audience;
        options.ClaimsIssuer = TokenProviderOptions.Issuer;
        options.TokenValidationParameters = tokenValidationParameters;
        options.SaveToken = true;
    });
    var policy = new AuthorizationPolicyBuilder()
    {
        AuthenticationSchemes = new[] { "Bearer" }
    }
    .RequireAuthenticatedUser()
    .Build();

    services.AddMvc(options =>
    {
        options.Filters.Add(new AuthorizeFilter(policy));
    });
}
0 Likes

#19

Thanks Atanas, it's working now.

Regards

0 Likes

#20

This code would need to be removed once we release the updated version of Radzen. I will let you know.

0 Likes