TRIM: Permissions error creating a record through Web service API - trim

HP TRIM 8.0
I am trying to create a record using Service API and getting this error message, but I can successfully create a todo item, Missing any permission settings?
2016-07-22 10:15:36,661 [20] ERROR ServiceStack.DtoUtils - ServiceBase<TRequest>::Service Exception
HP.HPTRIM.SDK.TrimException: You do not have create record access for this Record Type.
at HP.HPTRIM.SDK.Record..ctor(RecordType recordType)
at HP.HPTRIM.Service.RecordConstructor.Construct(Database database, TrimObject trimObject)
at HP.HPTRIM.Service.Extensions.FindOrCreateTrimObject(TrimMainObject trimObject, Database database)
at HP.HPTRIM.Service.TrimObjectUpdater`1.<getTrimMainObjects>d__0.MoveNext()
at HP.HPTRIM.Service.TrimObjectUpdater`1.update(T request, IRequest requestContext, Action`1 action)
at HP.HPTRIM.Service.RecordDocumentServiceBase.DoPost(Record request)
at HP.HPTRIM.Service.RecordDocumentService.Post(Record request)
at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)

The Error clearly states the user does not have permission to create the particular record type. Make sure the apppool user is added as trusted user.

Related

How to catch an http post abortion due to bad connection in ASP.NET Core Web API?

I am programming a fullstack application which is used on festivals to monitor their inventory on bars (how many bottles of gin they have for instance). It allows for creating an transfer request to get more stuff to specific bar and looking up those requests. The problem arises when the connection is slow enough to cause a timeout (by my testing at 1KB/s upload/download throttle it took approx 10s) but still send the data to the API.
My method which handles writing the data to the database looks like this:
public IActionResult WriteStorageTransfer([FromBody] StorageTransfer transfer)
{
Console.WriteLine("Started the execution of method");
var transferId = database.CreateNewDoc(transfer);
foreach (var item in transfer.items)
{
var sql = #$"insert into sklpohyb(idsklkarta, iddoc, datum, pohyb, typp, cenamj, idakce, idbar, idpackage, isinbaseunit)
values ({item.id}, {transferId}, current_timestamp, {packMj}, {transfer.typ}, {item.prodejnicena}, {transfer.idakce}, {transfer.idbar}, case when {pack.idbaleni} = -1 then NULL else {pack.idbaleni} end, {pack.isinbaseunit})";
database.ExecuteQueryAsTransmitter(sql);
}
return Ok(transferId); // transferId is then used by frontend to display the created transfer request.
}
This would be all nice and all, but the frontend appears to send the data to the API, API processes it and writes it to the database, but then timeout occurs on the HttpRequest, crashing the method, thus never returning a HttpResponse to the frontend (or returning code 0: 'Unknown error').
The exception thrown by the API:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.IO.IOException: The request stream was aborted.
---> Microsoft.AspNetCore.Connections.ConnectionAbortedException: The HTTP/2 connection faulted.
--- End of inner exception stack trace ---
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.GetReadAsyncResult()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2MessageBody.ReadAsync(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 destination, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.ReadFromStreamAsync(Stream utf8Json, ReadBufferState bufferState, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.ReadAllAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object valu
e, Object container)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
The size of the JSON sent to API is usually ~10 KB, nothing too serious like 100MB so I don't think the size is the problem
This leaves the frontend hanging and the users tend to click the button again, possibly writing multiple duplicates to the database as he does not know if the invoice has been processed or if there is an error in the app.
Interestingly the Console.Write("Started execution of the method") does not get triggered as I do not see it in the console window, yet the data gets written into the database after manually checking it.
Perfect thing would be if I could notify the user that something went wrong in the creation of the transfer request, and prevented the creation of it in the database. I tried using try catch block targeted on IOException
Thanks a lot in advance, anything goes at this point
The problem arises when the connection is slow enough to cause a timeout but still send the data to the API.
Back to the drawing board (or time to give us more details). If your POS app (which I assume this is) wants to report a sale to the back-end, why would the user have to wait for this? And why would the user be able to report one sale twice?
Instead have the client generate a unique transaction ID locally and store them in local storage, and (after each sale, and periodically, but most importantly: on the background) have the client try to synchronize their transactions to the server. The server can then reject duplicate transactions so it won't record the same sale twice, and your app can handle periods without or with spotty internet access.
As for your error: the timeout probably is a minute or so, which may be too long for this use case anyway. The client will ultimately throw an exception if it doesn't get an HTTP response, but do you want your bar person to wait on the POS for a minute? They are going to call it a POS then.

How can I setup my ASP.NET backend in IIS?

I am building a website that is managed over Microsoft IIS. I want my whole website to work like this:
The IIS gets a HTTP request over port 80 for the main website and then answers with the HTML and JS documents. These documents remain static and are simply saved as files on the server, which the IIS reads and send to the client without further modifying it.
In the JS document that the client gets, there are fetch()-commands that send additional requests during runtime over a different port when the user is interacting with the website. The browser should get back JSON data from the server. I have written a ASP.NET web application to do this.
This is what my current setup in IIS looks like:
enter image description here
I have set up a site for step one (front-end) and one for step two (back-end). I added a binding for the first site to port 80 and set the default document. I linked the second site to the directory in which the build binary of my ASP.NET application lies. Then, I added the binding with Port 5000 and the same IP-Address to the second site.
Step one works. When sending a request over Port 80, I get the website documents. But the second step doesn't. In debugging mode of Visual Studio, it works fine and it does it job. But I didn't manage to get step two working in IIS yet. The response I get when sending my requests is a 404. I created an additioonal controller to my back-end for testing that should just respond some hardcoded strings and do nothing more. Actually that works. I do get a 200 and the strings as a response. So there must be something wrong with the ASP.NET back-end communicating with my database.
I found out that everytime, when sending my request, an error log is written by my back-end. It says:
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware1
An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
Again, I do not get the error when debugging the back-end ap
Can someone help?
The problem was basically wrong SQL Server permission setup. I managed to solve my problem. This may be helpful to people who are facing similar problems:
The "JsonException object cycle" error itself was not that helpful at all. So, I went into further debugging. I attached VisualStudio Debugging to the actual running IIS process like so: https://learn.microsoft.com/en-us/visualstudio/debugger/attach-to-running-processes-with-the-visual-studio-debugger?view=vs-2019
This was helpful for finding the reason for the error, as I could now experience log messages that were much more fitting to the actual error. Mind that you have to change the hostingModel to "outofprocess" in the web.config in order to attach to the standalone .Net process. https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/out-of-process-hosting?view=aspnetcore-5.0
In case you are using SQL Server Management Studio, create a login for "NT Authority" (Object Explorer > Security > Logins > NT-Authority), grant access to your database and make sure that you do not select a "deny" role in user mapping, because I did so, and that was causing my error.

Error/Stack Trace

ServiceStack version 5.0.2
I wondered if anyone could give me a pointer to a possible cause of the error shown in the stack trace below. (I am a junior developer, so I am very new to all this.)
We have an ASP.net MVC application which has some ServiceStack.Mvc integration in it. (I suspect we are using ServiceStack's auth provider functionality to handle authentication on MVC controller action requests).
Today we witnessed errors appearing when trying to login to our Web Application. Below is the stack trace of one of the errors that appeared.
The Index action on "MyController" has an 'Authenticate' attribute on it.
[Authenticate]
public class MyController : ServiceStackController<AuthUserSession>
All I can deduct from the stack trace is that after the MVC controller action is invoked, the service stack ServiceRunner tries to execute a service (I have no idea which one) and there is somekind of null reference within the execute method which is throwing an exception.
I wondered if Myths or anyone else had ever seen this before, or could shed any light whatsoever on what service the service runner may have been trying to execute or any information on a possible cause.
The issue disappeared after the web server was rebooted
Exception type: NullReferenceException
Exception message: Object reference not set to an instance of an object.
Stack trace: at ServiceStack.DtoUtils.CreateErrorResponse(Object request, Exception ex)
at ServiceStack.Host.ServiceRunner`1.HandleException(IRequest request, TRequest requestDto, Exception ex)
at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)
at ServiceStack.Host.ServiceRunner`1.Process(IRequest requestContext, Object instance, Object request)
at ServiceStack.Host.ServiceExec`1.Execute(IRequest request, Object instance, Object requestDto, String requestName)
at ServiceStack.Host.ServiceRequestExec`2.Execute(IRequest requestContext, Object instance, Object request)
at ServiceStack.Host.ServiceController.ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, Object requestDto)
at ServiceStack.Host.ServiceController.<>c__DisplayClass36_0.<RegisterServiceExecutor>b__0(IRequest req, Object dto)
at ServiceStack.Host.ServiceController.Execute(Object requestDto, IRequest req)
at ServiceStack.InProcessServiceGateway.ExecSync[TResponse](Object request)
at ServiceStack.InProcessServiceGateway.Send[TResponse](Object requestDto)
at MyApplication.Controllers.MyController.Index()
I've not seen this error before, but the StackTrace originated from your MyController.Index() Action.
The ServiceStackController doesn't use the Gateway, neither does the ExecuteServiceStackFilters which executes the AuthenticateAttribute on your MVC Controller. So I'd say it's something in your MyController.Index() implementation that's causing it.

Isolating specific browser instance with SignalR

We are building an app which will send messages to the browser using SignalR. The user may have multiple browser instances open and we would like each message to be sent to the appropriate browser. Our understanding is that the ClientId ConnectionId would allow us to do this. The issue we're running into is accessing the ClientId ConnectionId, or SessionId, at the appropriate times in the codebase. Here's our scenario:
A MVC Action executes and, as part of that processing, a call to a Biztalk endpoint is made. The Biztalk execution is out of process (from the point of view of the MVC Action) and doesn't return when completed. This is by design. To notify the MVC application that it has completed, Biztalk sends a message to the MVC application's SignalR hub by calling the /myapp/signalr endpoint. The message is received by SignalR and then should be routed to the appropriate browser instance.
Since the message to SignalR is being sent by Biztalk, and not the MVC application, the ClientId of the connection to SignalR is not the one that identifies the browser instance that should receive the message. So what we are attempting to implement is somethign similar to the Return Address pattern by including the ClientId ConnectionId of the browser instance that initiates the Biztalk call in the message to Biztalk. When Biztalk sends its message to SignalR one of the contents is that original ClientId ConnectionId value. When SignalR processes the message from Biztalk it then can use the ClientId ConnectionId included in the message to route that message to the appropriate browser instance. (Yes we know that this won't work if the browser has been closed and re-opened and we're fine with that.)
The problem we face is that when initially sending the message to Biztalk from our MVC Action we cannot access the ClientId ConnectionId as it's only available in the Hub's Context. This is understandable since the MVC Action doesn't know which Hub context to look for.
What we have tried in it's place is to pass the SessionId through the Biztalk message and return it to SignalR. This solves the problem of including the browser instance identifier in the Biztalk message and returning it to SignalR. What it introduces is the fact that when a client connects to the Hub we cannot access the Session (and thus the SessionId) in the Hub's OnConnect method.
David Fowler posted a gist that reportedly shows how to make readonly SessionState accessible in a Hub but it doesn't work. (https://gist.github.com/davidfowl/4692934) As soon as we add this code into our application messages sent to SignalR cause a HTTP 500 error which is caused by SignalR throwing the following exception.
[ArgumentNullException: Value cannot be null.Parameter name: s]
System.IO.StringReader..ctor(String s) +10688601
Microsoft.AspNet.SignalR.Json.JsonNetSerializer.Parse(String json, Type targetType) +77
Microsoft.AspNet.SignalR.Json.JsonSerializerExtensions.Parse(IJsonSerializer serializer, String json) +184
Microsoft.AspNet.SignalR.Hubs.HubRequestParser.Parse(String data) +101
Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) +143
Microsoft.AspNet.SignalR.<>c__DisplayClassc.<ProcessRequest>b__7() +96
Microsoft.AspNet.SignalR.<>c__DisplayClass3c.<FromMethod>b__3b() +41
Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod(Func`1 func) +67
No matter the mode that we set SessionStateBehavior (as shown by David Fowler's gist) we either get this exception when sending a message to the Hub or SessionState is null when we are in the Hub's OnConnect.
So, after all that pre-amble, what we are asking is how do people update the appropriate client when working with this type of disconnected messaging in SignalR?
If you're looking to send data to clients outside of a normal request to a hub then I'd recommend having a static Concurrent Dictionary on your hub that manages your users and maps them to corresponding connection Id's.
With this approach you can send to any user at any point based on their mapped Connection Id. Therefore when sending your data to Biztalk all you need to do is send your user id (created by you) and then when the data flows back to SignalR you can lookup the ConnectionId (if one exists) for that given user id.
Lastly, you can manage your user mappings by adding users to your concurrent dictionary in OnConnected, adding only if they are not there in OnReconnected, and removing in OnDisconnected.

log4net permission issue to write to application event log when the user is not in admin group in Windows 2008 R2 and IIS 7

I am having log4net permission issue from ASP.Net 4.0 web application to write to application event log, when the user is not in administrator group in Windows 2008 R2 and IIS 7. We are using NT authentication and impersonation. Once I assign the user to admin group it works fine.
I tried with many permission settings like giving Authenticated Users full permission to Eventlog in registry etc. and none of them work. If any one can help that will be great.
When I had a similar issue with logging to eventlog from a .net 1.1 app on Windows 2003 server I did CustomSD entry as below link and it worked
http://mossipqueen.wordpress.com/2008/08/04/cannot-open-log-for-source-you-may-not-have-write-access/
The error I get is below from log4net internal log.
log4net:ERROR [EventLogAppender] Unable to write to event log [Application] using source [*******]
System.InvalidOperationException: Cannot open log for source '*******'. You may not have write access. ---> System.ComponentModel.Win32Exception: Access is denied
--- End of inner exception stack trace ---
at System.Diagnostics.EventLogInternal.OpenForWrite(String currentMachineName)
at System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32 eventID, UInt16 category, EventLogEntryType type, String[] strings, Byte[] rawData, String currentMachineName)
at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String source, String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at log4net.Appender.EventLogAppender.Append(LoggingEvent loggingEvent)
Maybe I'm missing something here but it looks like a simple permissions issue for that user. By default they don't have access to write to the application log file. I know you played around with the permissions but I'm not sure exactly what permissions you assigned.
Here is a Microsoft article on doing exactly what you want to do to overcome the error you are seeing:
http://support.microsoft.com/kb/2028427
If you follow this, you should solve your issue. I hope this helps.

Resources