ASP.NET Web API cause exceptions while running on raspberry pi 2 (ARM) - sqlite

I have coded a Web API in Ubuntu using .NET Core recently and I need to use database to store the application data so that I decided to use EF Core. I ran this project on Ubuntu machine and everything worked appropriately.
I've also tried to run it on my raspberry pi 2 but I wasn't lucky enough to make it work properly. I did the instruction on this website and got this output as soon as I tried to access the api/dooz on Firefox while accessing my RP through Remmina Remote Desktop.
If the problem is with the database, how can I include the .db file to the iDooz_1/bin/Release/netcoreapp2.1/linux-arm/publish folder to make it work?
How can I solve it?
c343#RP:~/publish_idooz1$ ./iDooz_1
Hosting environment: Production
Content root path: /home/c343/publish_idooz1
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLFUSJJ3S54N", Request id "0HLFUSJJ3S54N:00000001": An unhandled exception was thrown by the application.
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Players'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)
at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.GetResult[TResult](IEnumerable`1 valueBuffers, Boolean throwOnNullResult)
at lambda_method(Closure )
at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ResultEnumerable`1.GetEnumerator()
at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_1`1.<CompileQueryCore>b__0(QueryContext qc)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
at iDooz.Controllers.DoozController..ctor() in /home/c343/Documents/iDooz_1/Controllers/DoozController.cs:line 24
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
^CApplication is shutting down...
However, api/values, the default API in the webapi application worked properly and I got the correct output as in I got earlier on Ubuntu.
NOTE: First, this project is generally made to build a Tic Toc Toe and to learn about REstful APIs using ASP.NET Core Web API. So, I made a database using Entity Framework called Dooz.db and that is in the main directory of the project. Second, I'm doing dotnet publish -c Release -r linux-arm because the .NET Core SDK is not available for ARM-Processors.
Third, this is the part of the code in which the terminal had output an error
at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
at iDooz.Controllers.DoozController..ctor() in /home/c343/Documents/iDooz_1/Controllers/DoozController.cs:line 24
Here is the code:
public class DoozController : ControllerBase
{
public DoozController()
{
if(db.Players.Count() == 0)
{
db.Players.Add(new Player { PlayerID = 1, Username = "Alex123", Password = "1234", ProfilePic = "ProfilePics/Alex123.jpg" });
db.Players.Add(new Player { PlayerID = 2, Username = "Ashkan_007", Password = "12345", ProfilePic = "ProfilePics/Ashkan_007.jpg" });
.
.
.
db.SaveChanges();
}
}
.
.
.

You need to copy the database file into publish folder.

Related

Access denied error using asymmetric binding in web host server - .NET

I'm getting an Access denied error when I attempt to make a web service request. The web service requires an asymmetric security binding. The call is made via a webpage that references a .NET dll that references the web service. All of this works fine on our server but we loaded it up at a web hosting company we got hit with this error.
My theory is that whatever the GetKeyPairHelper method does it requires the ability to write a file to do it while we don't have access to the location it tries to write to. The support people at this company ran a trace for us and these were the last two lines:
06:03.1 w3wp.exe 5860 CreateFile C:\ProgramData NAME COLLISION >Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: >Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, >Write, AllocationSize: 0
06:03.1 w3wp.exe 5860 CreateFile C:\ProgramData ACCESS DENIED >Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, >Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
Looks like something trying to write to C:\ProgramData but what? And why? And how do I get around it? I'm hoping there is some way to configure this so it doesn't have to write a file. Perhaps this job can be performed in memory or directed to an area we have access to.
Stacktrace:
Error: Access is denied. : Server stack trace:
at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.get_PrivateKey()
at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm)
at System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey)
at System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CompletePrimarySignatureCore(SendSecurityHeaderElement[] signatureConfirmations, SecurityToken[] signedEndorsingTokens, SecurityToken[] signedTokens, SendSecurityHeaderElement[] basicTokens)
at System.ServiceModel.Security.SendSecurityHeader.CompleteSignature() at System.ServiceModel.Security.SendSecurityHeader.CompleteSecurityApplication()
at System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.Message.WriteMessage(XmlWriter writer)
at CustomMessageEncoder.CustomTextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
in C:\xxxxx\CustomEncoders\CustomTextMessageEncoder.cs:line 86
Code:
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
MemoryStream stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
message.WriteMessage(writer); //'line 86' in stacktrace.
writer.Close();
byte[] messageBytes = stream.GetBuffer();
int messageLength = (int)stream.Position;
stream.Close();
int totalLength = messageLength + messageOffset;
byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
//maybe parse message around here...
ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
return byteArray;
}
What happened here is that the hosting company was hosting our site on a shared server and so rightfully denied access to the C:\ProgramData folder which, further down the directory contains C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys which is the folder you need access to in order to use certificates based security. Their solution for us was to allow access to this folder for our app pool only. Works like a charm.

Executing a Quartz.NET job from a separate assembly

I'm trying to execute a Quartz.net job from a separate assembly. The class inherits from the IJob interface, implements the Execute method, and has been copied into the same folder as Quartz.Server.exe, but I'm getting the following error:
Error scheduling jobs: Could not load file or
assembly 'TestJobs' or one of its dependencies. An attempt was made to load a p
rogram with an incorrect format.
System.BadImageFormatException: Could not load file or assembly 'TestJobs' or on
e of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'TestJobs'
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError,
Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, Bool
ean loadTypeFromPartialName, ObjectHandleOnStack type)
... (snipped)
I'm using version 2 beta 2. The server application has been unzipped into a separate folder and is being executed by running Quartz.Server.exe at the command line.
My sample job is a separate assembly named TestsJobs with a very basic job to write to a text file:
public class TestJob : IJob
{
public void Execute(IJobExecutionContext context)
{
try
{
string path = #"c:\test.txt";
while (true)
{
var line = DateTime.Now.ToString() + " - " + Guid.NewGuid();
File.AppendAllText(path, line);
Thread.Sleep(500);
}
catch (Exception ex)
{
throw new JobExecutionException("Error", ex, false);
}
}
}
}
This is a basic class library project targeting .NET 4. It is copied into the Quartz.Net server folder where Quartz.Server.exe is being run from.
The quartz_jobs.xml file has the job set using the default file, with just the job type changed to reflect the new assembly and class:
<job-type>TestJobs.TestJob, TestJobs</job-type>
Thought this might be something to do with framework versioning, but Quartz.net seems to be using .NET 4 as well (Quartz.dll has dependencies on v4 assemblies).
There's another question on SO about the same type of issue, but it doesn't have a clear answer.
Is there anything else I need to do so that the job can be loaded and executed?
The solution to this turned out to be a bit simpler that I thought. It was caused by my assembly with the test job being compiled for x86 instead of AnyCPU (or x64) and using Windows 7 x64.

Can I use SQL Server CE in a medium trust environment by just deploying the DLLs

I've written an ASP.NET 4.0 application that is using a SQL Server CE 4.0 database. This is all working on my development environment using Medium Trust (same trust config as the hoster). On this machine, I've gone through the install process (downloaded and installed the MSI). I'm now trying to deploy this solution to my web hoster.
The code that is running is (this is a straight out copy of the Altairis Membership Provider:
using (HostingEnvironment.Impersonate())
using (var db = this.connectionString.CreateDbConnection())
using (var cmd = this.CreateDbCommand("SELECT PasswordHash, PasswordSalt FROM $Users WHERE UserName = #UserName AND IsApproved = 1", db))
{
cmd.AddParameterWithValue("#UserName", username);
db.Open();
// Validate password
using (var r = cmd.ExecuteReader()) { .. snip.. }
}
In the instance above, db is DbConnection, and cmd is DbCommand
I'm getting the following error:
[InvalidOperationException: Cannot perform CAS Asserts in Security Transparent methods]
System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken
permToken, CodeAccessPermission demand, StackCrawlMark& stackMark,
Int32 create) +0
System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission
cap, StackCrawlMark& stackMark) +61
System.Security.CodeAccessPermission.Assert() +28
System.Data.SqlServerCe.KillBitHelper.GetKillBit() +231
System.Data.SqlServerCe.KillBitHelper..cctor() +56
[TypeInitializationException: The type initializer for 'System.Data.SqlServerCe.KillBitHelper' threw an exception.]
System.Data.SqlServerCe.KillBitHelper.ThrowIfKillBitIsSet() +0
System.Data.SqlServerCe.SqlCeProviderFactory..cctor() +41
[TypeInitializationException: The type initializer for 'System.Data.SqlServerCe.SqlCeProviderFactory' threw an exception.]
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeFieldHandle.GetValue(RtFieldInfo field, Object instance, RuntimeType fieldType, RuntimeType declaringType, Boolean&
domainInitialized) +0
System.Reflection.RtFieldInfo.InternalGetValue(Object obj, Boolean doVisibilityCheck, Boolean doCheckConsistency) +180
System.Reflection.RtFieldInfo.GetValue(Object obj) +8
System.Data.Common.DbProviderFactories.GetFactory(DataRow providerRow) +232
System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName) +88
Altairis.Web.Security.DatabaseExtensionMethods.CreateDbConnection(ConnectionStringSettings
settings) in DatabaseExtensionMethods.cs:19
Altairis.Web.Security.TableMembershipProvider.ValidateUser(String
username, String password) in TableMembershipProvider.cs:361
I've used a decompiler to look through the code, and it seems that the internals of SQL Server CE are looking for a registry entry and then trying to do a code Assert().
Is it possible to use SQL Server CE 4.0 in a partial trust environment, by just \bin deploying the DLL ??
Yes, provided your hoster allows it - it is allowed by default in ASP.NET 4.0. Make sure you use assembly version 4.0.0.0 (and not 4.0.0.1). Read more here: http://erikej.blogspot.com/2011/10/sql-server-compact-40-under-aspnet.html

If a ASMX WebService needs a DLL where should it be put?

I'm using some 3rd party software that's failing. Their API is wrapped in a ASP web service.
The call stack tells me that it needs maybe MySQL.Data.DLL or something (not sure exactly) in the correct directory. So I'm wondering where that directory would be. The Web Server is IIS.
Here is the call stack:
Unable to find the requested .Net Framework Data Provider. It may not be installed.
at System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName)
at WebReports.Api.Data.SqlObject.CreateConnectionObject(String dbType, String dataConnStr)
at WebReports.Api.Data.SqlObject..ctor(PageInfo pageInfo, Int32 dataSourceId)
at WebReports.Api.Data.DataObjectBase.GetDataObject(PageInfo pageInfo, Int32 dataSourceId, String objectType, Boolean isSqlSpecific)
at WebReports.Api.Reports.Entity.get_DataSource()
at WebReports.Api.Reports.Entity.GetColumnProcess(String colName, Boolean isActual)
at WebReports.Api.Reports.EntityColumnsCollection.GetColumnProcess(String colNameFull, Boolean isActual)
at WebReports.Api.Common.PageInfo.GetMnemonicFromId(String id)
at WebReports.Api.Reports.KeyColumnCollection.SetColumnMnemonics()
at WebReports.Api.Reports.ReportEntityCollection.SetColumnMnemonics()
at WebReports.Api.Reports.ReportEntityCollection.LoadData(DataSet ds, Boolean readSchema)
at WebReports.Api.Reports.Report.get_Entities()
at WebReports.Api.Common.PageInfo.GetMnemonicFromId(String id)
at WebReports.Api.Reports.Cell.set_SaveText(String value)
at WebReports.Api.Reports.ReportCellCollection.LoadData(DataSet ds)
at WebReports.Api.Reports.Report.get_Cells()
at WebReports.Api.Reports.Report.UpdateVersion()
at WebReports.Api.Reports.Report.Validate(Boolean validateJoins)
at WebReports.Api.Reports.Report.LoadData(Boolean validate)
at WebReports.Api.Reports.Report.Load(String reportName)
Above this line is their API, so I can't inspect it:
at eWebReportsLETG.ReportURLService.GenerateReportURL(Int32[] list, String m_szWebReportsVirtualDirectory, String m_szWebReportsUrl, String ReportDir, String ReportName, String PkSpecialName, Boolean& Failed) in C:\dev\eWebReports\eWebReportsLETG\ReportURLService.asmx.cs:line 51
I needed to copy MySQL.data.dll to the bin directory of my web service application directory. I also added the config key to the web.config.

Com Exception: Word was unable to read this document. It may be corrupt

I have a web app that takes some client info and produces a letter for each client. Everything works good in my test environment, but on the production server I get an error that says the file is corrupt. I can open the .dotx file in word just fine on the server but not via code. Please help. Here is my code:
Object oMissing = System.Reflection.Missing.Value;
Object oTrue = true;
Object oFalse = false;
Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();
oWord.Visible = false;
Object oTemplatePath = Request.PhysicalApplicationPath + "letters\\" + letter.letter_data; //samplehollisletter.dotx";
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
foreach (Word.Field myMergeField in oWordDoc.Fields)
{
iTotalFields++;
Word.Range rngFieldCode = myMergeField.Code;
String fieldText = rngFieldCode.Text;
if (fieldText.StartsWith(" MERGEFIELD"))
{
Int32 endMerge = fieldText.IndexOf("\\");
Int32 fieldNameLength = fieldText.Length - endMerge;
String fieldName = fieldText.Substring(11, endMerge - 11);
fieldName = fieldName.Trim();
if (fieldName == "letter_title")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.letter_title);
}
if (fieldName == "account_id")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.account_id);
}
if (fieldName == "address")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.PEOPLE.home_address + "\r\n" + acct.PEOPLE.home_city + ", " + acct.PEOPLE.home_state + " " + acct.PEOPLE.home_zip);
}
if (fieldName == "greeting_title")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.greeting_title);
}
if (fieldName == "service_name")
{
myMergeField.Select();
oWord.Selection.TypeText((acct.SERVICEs.FirstOrDefault()).service_name);
}
if (fieldName == "service_date")
{
myMergeField.Select();
oWord.Selection.TypeText((acct.SERVICEs.FirstOrDefault()).service_date.ToString());
}
}
}
oWordDoc.PrintOut();
oWordDoc.Close(Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges);
Thread.Sleep(2000);
oWord.Quit();
The Error is:
Server Error in '/Tracker2' Application.
Word was unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and Repair the file.
* Open the file with the Text Recovery converter.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Word was unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and Repair the file.
* Open the file with the Text Recovery converter.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[COMException (0x800a141f): Word was unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and Repair the file.
* Open the file with the Text Recovery converter.]
Microsoft.Office.Interop.Word.Documents.Add(Object& Template, Object& NewTemplate, Object& DocumentType, Object& Visible) +0
Tracker.RunLetter2.Button1_Click(Object sender, EventArgs e) in C:\Users\Ethan\Documents\Visual Studio 2010\Projects\EstateTracker\Tracker\RunLetter2.aspx.cs:52
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +154
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3691
I know it is time that this item has been opened, but as I had not found the answer anywhere, following solution for those who need it.
1 - In IIS, the application pool used by the application, change the Identity attribute to LocalSystem
2 - Create a folder called Desktop within the following directories on the server:
C:\Windows\System32\config\systemprofile
and
C:\Windows\SysWOW64\config\systemprofile
After that, give full permission for these two folders to the user group IIS: IIS_IUSRS
This will cause this user to have a "desktop" to work, thereby achieving the IIS Word use the library.
I rough it helps someone.
I have discovered that the issue stems from permissions of a WCF call using BasicHTTPBinding endpoints. When a call is made using this type of endpoint, the service assumes the use of an IIS account which does not have a desktop to open word. This is a requirement of the account to automate word. Even when you have a service, that launches a windows application, that launches word, the entire set of events will be given the privilage of the original WCF call and will result in this error.
My solution, while not great, nor what I really want, does work for the time being. I created a Queue table in the database. I then have the web app insert a request for a task to be completed. then on the server I have a standalone application that checks the queue for requests every 60 seconds and processes the request. Its not the best method boe like I said, it does work.

Resources