Elmah.MVC + NLog - store all errors in one place - sql-server

I'm working on an ASP.NET MVC 5 app in Visual Studio 2015. We use NLog to write some errors and other information to the database in our try/catch blocks. However, it would be nice to also implement ELMAH.MVC, so that any/all uncaught exceptions get caught/logged and the user redirected to a friendly page.
Here's our NLog table structure; note that ApplicationId is not equivalent to Application on the ELMAH_Error table; people apply for things through the app, and this is the ID we assign when they start the process. And RouteId is not an MVC route.
CREATE TABLE [dbo].[Log](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ApplicationId] [int] NULL,
[RouteId] [int] NULL,
[MachineName] [varchar](50) NULL,
[TimeStamp] [datetime2](7) NULL,
[LogLevel] [varchar](5) NULL,
[Logger] [nvarchar](max) NULL,
[Message] [nvarchar](max) NULL,
[Exception] [nvarchar](max) NULL,
[StackTrace] [nvarchar](max) NULL,
CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
The SQL for ELMAH's table looks like this (from the script here):
CREATE TABLE [dbo].[ELMAH_Error]
(
[ErrorId] UNIQUEIDENTIFIER NOT NULL,
[Application] NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Host] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Type] NVARCHAR(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Source] NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Message] NVARCHAR(500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[User] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[StatusCode] INT NOT NULL,
[TimeUtc] DATETIME NOT NULL,
[Sequence] INT IDENTITY (1, 1) NOT NULL,
[AllXml] NTEXT COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
)
ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Is it possible to have the ELMAH_Error table contain the additional columns found on the NLog Log table, or vice versa? How can I write errors from NLog to the ELMAH table?
Thank you.
Update 1: Came across this: https://github.com/ccellar/nlog-elmah-target, but it lacks any documentation on how you use it. Would this redirect all NLog exceptions to ELMAH?
Update 2: A related question has been asked about adding the Exception.Data dictionary to ELMAH. This way, any number of key/value pairs can be added to what Elmah stored. This way, all the data now stored with NLog would be stored on ELMAH.

Found a solution that works very nicely: https://github.com/NLog/NLog.Elmah/
To install,
Install-Package NLog.Elmah
Update-Package NLog
I also installed NLog.Web package, but isn't required for this.
Modify NLog.config to include:
<targets><target name="target1" xsi:type="Elmah" LogLevelAsType"false" /></targets>
<rules><logger name="*" minlevel="Info" writeTo="target1" /></rules>
Now just decorate any controller/class that uses NLog with the target:
[Target("Elmah")]
public class HomeController : Controller
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
public ActionResult Index()
{
// Other code...
var logEvent = new LogEventInfo(LogLevel.Info, _logger.Name, "Some information...");
_logger.Log(logEvent);
// Other code...
}
}
You can also throw the attribute on a base controller/class and cover all your application.

Related

Cannot delete regs on a SQL table in Access

I have a SQL Server table linked in an Access app. If I try to delete records with a delete query there is no problem. But if I try to delete records directly in table or using a select query in datasheet mode Access doesn't allow me to delete the records and throws the following warning:
"The microsoft access database engine stopped the process because you and another user are attempting to change the same data at the same time."
The same happens when I try to update data. There is no other user modifying the data.
The problem is that we still have a lot of legacy forms that uses datasheet mode to alter o delete records instead of using queryes and, for now, changing all these forms is unthinkable.
¿Has anyone any idea of what could be happening?
Thanks!
FINAL EDIT:
The problem was a bit field that was set to nullable that, thanks to Kostas K. I discovered is not convertable to Access.
So, instead of this:
[FIELD] [bit] NULL
We need tis:
[FIELD] [bit] NOT NULL
ALTER TABLE [dbo].[TABLE] ADD DEFAULT ((0)) FOR [FIELD] GO
UPDATE: This locking only happens with new records added from Access, but not with the original records of the SQL table.
This is the script to create the table:
`
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Chapas].[INFO_CHAPAS](
[ID_INFO_CHAPA] [int] IDENTITY(1,1) NOT NULL,
[COD_EQUIPO] [int] NULL,
[EQUIPO] [nvarchar](255) NULL,
[NUMERO_SERIE] [nvarchar](255) NULL,
[FASES] [nvarchar](255) NULL,
[VOLTAJE] [nvarchar](255) NULL,
[FRECUENCIA] [nvarchar](255) NULL,
[POTENCIA] [nvarchar](255) NULL,
[AÑO] [int] NULL,
[IMPRESO] [bit] NULL,
[SELECTOR_REGISTRO] [bit] NULL,
[USUARIO] [int] NULL,
[FECHA_IMPRESION] datetime NULL
CONSTRAINT [INFO_CHAPAS_PK] PRIMARY KEY NONCLUSTERED
(
[ID_INFO_CHAPA] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY
= OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [Chapas].[INFO_CHAPAS] ADD DEFAULT ((0)) FOR [IMPRESO]
GO
`

SQL Table Schema for IdentityServer4 PersistedGrantStore

I'm writing a PersistedGrantStore for IdentityServer 4 and want to persist to a Table in SQL server.
PersistedGrant has a key of type string, not a great choice but I'll use binary collation to compensate. nvarchar(max) for a primary key is a no-go as long as I get to play the DBA role.
Could anyone give us an indication on how long this field and all other string fields should be?
Key
Type
SubjectId
SessionId
ClientId
Description
Data
It would also be great to know beforehand if we should add indexes for any of the fields ending with Id.
The table create SQL statement is:
USE [IdentityServer]
GO
/****** Object: Table [dbo].[PersistedGrants] Script Date: 2021-12-21 21:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[PersistedGrants](
[Key] [nvarchar](200) NOT NULL,
[Type] [nvarchar](50) NOT NULL,
[SubjectId] [nvarchar](200) NULL,
[SessionId] [nvarchar](100) NULL,
[ClientId] [nvarchar](200) NOT NULL,
[Description] [nvarchar](200) NULL,
[CreationTime] [datetime2](7) NOT NULL,
[Expiration] [datetime2](7) NULL,
[ConsumedTime] [datetime2](7) NULL,
[Data] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_PersistedGrants] PRIMARY KEY CLUSTERED
(
[Key] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
You can find the SQL code for all the tables here

How to fix "There is already an object named ' ' in the database" error in sql server

I have created this table, I can't enter data manually because of this error.
USE [Butterfly]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[VM_Vehicles](
[VehicleID] [nvarchar](100) NOT NULL,
[VehicleType] [nvarchar](100) NULL,
[RegistrationNo] [nvarchar](100) NULL,
[PurchaseDate] [date] NULL,
[Make] [nvarchar](100) NULL,
[Model] [nvarchar](100) NULL,
[ChassisNo] [nvarchar](100) NULL,
[EngineNo] [nvarchar](100) NULL,
[EngineCapacity] [nvarchar](100) NULL,
[YearofManufacture] [nvarchar](100) NULL,
[SeatingCapacity] [nvarchar](100) NULL,
[ContactName] [nvarchar](100) NULL,
[Phone] [nvarchar](50) NULL,
[VendorID] [int] NOT NULL,
[Picture] [image] NULL,
[VoucherNo] [int] NOT NULL,
CONSTRAINT [PK_VM_Vehicles1] PRIMARY KEY CLUSTERED
(
[VehicleID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
I have tried using this code to find what's wrong with my database. so far no luck finding error.
IF object_id("tempdb..#VM_Vehicles") is not null
DROP TABLE #VM_Vehicles
CREATE TABLE #VM_Vehicles (vehicleID nvarchar(100), ...);
I already tried changing constraint name and table name. That didn't provide me a answer either.
You are creating a persistent table VM_Vehicles in database Butterfly. However, you are checking a temporary table #VM_Vehicles in database TempDB:
IF object_id("tempdb..#VM_Vehicles") is not null
So you are checking another table from another database and so you have a such error:
There is already an object named ' ' in the database
The correct check statement should look like this:
USE Butterfly
IF OBJECT_ID("VM_Vehicles") IS NOT NULL DROP TABLE VM_Vehicles
CREATE TABLE [dbo].[VM_Vehicles](VehicleID nvarchar(100), ...);

How to set auto increment to existing primary column field in SQL Server [duplicate]

This question already has answers here:
Adding an identity to an existing column
(19 answers)
Closed 8 years ago.
I have created a SQL Server database table but forgot to set auto increment in the primary key column. How can I set the auto increment to the existing primary key field?
CREATE TABLE [dbo].[STUDENT_INFO]
(
[ROLLNO] [INT] IDENTITY(1, 1) NOT NULL,
[SCHOOLID] [INT] NOT NULL,
[STUDENTID] [INT] NOT NULL,
[NAME] [NVARCHAR](50) NOT NULL,
[AGE] [INT] NOT NULL,
[GENDER] [NVARCHAR](10) NOT NULL,
[ADDRESS] [NVARCHAR](500) NULL,
[CONTACTNO] [NVARCHAR](20) NOT NULL,
[EMAIL] [NVARCHAR](50) NULL,
[ISACTIVE] [BIT] NOT NULL,
[INSTRUMENTID] [INT] NOT NULL,
[GRADEID] [INT] NOT NULL,
[DISCOUNT] [INT] NOT NULL,
[STARTTIME] [TIME](7) NOT NULL,
[DURATION] [TIME](7) NOT NULL,
PRIMARY KEY CLUSTERED ( [STUDENTID] ASC ) WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
I am working with SQL Server Management Studio 2012.
I was about to say that it can't be done. That you have to drop and recreate the primary key (or, just create the entire table from scratch, move the data over, and drop the old table).
EDIT:
But depending on your version and edition of SQL Server, you may be able to use the object explorer to navigate to the table and access its design properties there. Where you can then set the column to an identity type.
However as someone pointed out, it may actually drop and recreate the table anyway in the background.
Anyway, as the OP already contains an edit to an answer the same as what I suggested at first (replacing the PK with another one, or recreating the table and moving the data there), I suppose there's no need to go further into this.

SQl Server 2012 error

I created a table manually and after that selected script table as new query and changed table name and executed the query. I am getting the error as
Msg 170, Level 15, State 1, Line 12 Line 12: Incorrect syntax near
'('.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE dbo.[KitCodeProperties](
[KitPropertiesId] [int] IDENTITY(1,1) NOT NULL,
[KitCodeName] [varchar](50) NULL,
[KitCodeDescription] [varchar](200) NULL,
[ShippingInstructions] [varchar](200) NULL,
[DepartmentId] [int] NULL,
[KitCodeActive] [bit] NULL,
CONSTRAINT [PK_KitCodeProperties] PRIMARY KEY CLUSTERED
(
[KitPropertiesId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
I took you code and pasted it into my 2012 developer edition. Had no issues creating the table with and without SET commands.
Therefore, the syntax looks good.
Are you selecting on a section of the window?
Make sure you are not selection anything in the new query window and press F5 to execute the whole window as one batch.
If this works, you were highlighting only a section of the code.
A simplified version of the SSMS code.
-- Remove old existing table
IF OBJECT_ID('[dbo].[KitCodeProperties]') > 0
DROP TABLE [dbo].[KitCodeProperties];
-- Create new table
CREATE TABLE [dbo].[KitCodeProperties]
(
[KitPropertiesId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
[KitCodeName] [varchar](50) NULL,
[KitCodeDescription] [varchar](200) NULL,
[ShippingInstructions] [varchar](200) NULL,
[DepartmentId] [int] NULL,
[KitCodeActive] [bit] NULL,
);
The cut down version works fine in SQL Fiddler.

Resources