Where predefined database (.db) should add and how to use it in windows phone 8.1 app?
I am not using Silverlight in my app.
I was trying to do something like this
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
CopyDatabase();
}
private void CopyDatabase()
{
IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();
String DBFile = "myDB.sqlite";
if (!ISF.FileExists(DBFile)) CopyFromContentToStorage(ISF, "Assets/myDB.sqlite", DBFile);
}
It showing that the namespace name IsolatedStorageFile could not be found.
I found those codes in a sample database app for Windows-phone-8.0 and I was trying to do the same thing in Windows-phone-8.1 (without Silverlight).
As I see you try to copy the database from package to IsolatedStorage and you are targeting WinRT. The sample code can llok like this:
private async Task<bool> CopyDatabase()
{
StorageFolder packageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await packageFolder.GetFileAsync("Assets/myDB.sqlite");
await file.CopyAsync(localFolder);
return true;
}
I've written this code from the top of my head, but should work or help you to find the solution. The above is also possible by Uri schemes:
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(#"ms-appx:///Assets/myDB.sqlite"));
More about Data and Files you will find at MSDN.
Related
I have my web api that uploads and reads an excel file from the client app and then afterwards saves the data into the database, the application works perfect on locally server but the problem comes when the application is deployed to azure server it returns error 500 internal server error therefore i don't understand why this happens and and don't know how i can track to understand what might be the cause below are my code blocks.
My Interface Class
public interface UploadExcelInterface
{
Task UploadMultipleClients(Client obj);
}
My Service Implementation
public class UploadExcelService : UploadExcelInterface
{
private readonly DbContext _connect;
private readonly IHttpContextAccessor httpContextAccessor;
public UploadExcelService(DbContext _connect, IHttpContextAccessor httpContextAccessor)
{
this._connect = _connect;
this.httpContextAccessor = httpContextAccessor;
}
public async Task UploadMultipleClients(Client obj)
{
var file = httpContextAccessor.HttpContext.Request.Form.Files[0];
if (file != null && file.Length > 0)
{
var folderName = Path.Combine("Datas", "ClientUPloads");
var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);
var fileName = Guid.NewGuid() + ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
var fullPath = Path.Combine(pathToSave, fileName);
var clientsList = new List<Client>();
using (var fileStream = new FileStream(fullPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
FileInfo excelFile = new FileInfo(Path.Combine(pathToSave, fileName));
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage package = new ExcelPackage(excelFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
var rowcount = worksheet.Dimension.Rows;
for (int row = 2; row <= rowcount; row++)
{
var Names = (worksheet.Cells[row,2].Value ?? string.Empty).ToString().Trim();
var Address = (worksheet.Cells[row,3].Value ?? string.Empty).ToString().Trim();
var Title = (worksheet.Cells[row,4].Value ?? string.Empty).ToString().Trim();
var Product = (worksheet.Cells[row,5].Value ?? string.Empty).ToString().Trim();
var Order = (worksheet.Cells[row,6].Value ?? string.Empty).ToString().Trim();
var Email = (worksheet.Cells[row,7].Value ?? string.Empty).ToString().Trim();
var Price = (worksheet.Cells[row,8].Value ?? string.Empty).ToString().Trim();
clientsList.Add(new Client
{
Names = Names,
Address = Address,
Title = Title,
Product = Product,
Order = Order,
Email = Email,
Price = Price,
}
}
//adding clients into the database
foreach (Client client in clientsList)
{
var exist = _connect.client.Any(x => x.Email == client.Email);
if (!exist)
{
await _connect.client.AddAsync(client);
}
}
await _connect.SaveChangesAsync();
}
}
}
My Controller Class
[HttpPost]
public async Task UploadMultipleClients([FromForm] Client obj)
{
await uploadExcelInterface.UploadMultipleClients(obj);
}
}
Please any help regarding this error that am getting from the server, and addition on that is it possible to get the data from the excel file without uploading it to server if yes how? because i tried adding the file to memory stream an reading it from memory but it appers not work, any suggestions thanks.
My answer may not help you solve the problem directly, but it can locate the error step by step. After we fix the error, we should be able to solve the problem in this thread.
Suggestions
Please make sure you have inclue EPPlus library in your deploy content.
Enabling ASP.NET Core stdout log (Windows Server)
Azure App Service - Configure Detailed Error Logging
Why
After tested, I am sure azure webapp can support EPPlus. For 500 error, as we don't have a more specific error message to refer to, we can't quickly locate the problem. Following the suggested method, you will surely see some useful information.
E.g:
The class library of EPPlus was not found.
Folders such as Datas are not created.
The database connection string, the test environment and the production environment may be different.
...
I have a website (webapi+c#+asp.net core) that serving files to the clients. The application expose the method to the Download file from the server.
The actual file is stored on Google Storage. So, the file is being downloaded to the server (stored in memory stream) and then returned to the caller.
This is my code:
[Route("download/{id}")]
[HttpGet]
public async Task<ActionResult> DownloadAsync(string id)
{
// Authentication...
Uri remoteFile = item.GetEnpointResponse(); // Path to file in bucket
using (StorageClient gcpStorage = await StorageClient.CreateAsync(remoteFile.GetCredentials().Credentials).ConfigureAwait(false))
{
MemoryStream ms = new MemoryStream();
await gcpStorage.DownloadObjectAsync("bucketName", "path/to/blob", ms, new DownloadObjectOptions
{
EncryptionKey = "XXX"
}).ConfigureAwait(false);
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "application/json");
}
}
Two problems I found:
It's storing all data of the file in the memory. If the file is large... its a hard job.
Waste of time - The file is being downloaded twice until getting to the client's hands.
Since this code is happening many times, I wonder if I can improve the performance of it? Something that I can improve here?
Most elegant way I could find is the following, using the library AspNetCore.Proxy:
namespace Storage
{
[Route("api/storage")]
public class StorageController : Controller
{
private readonly string _bucketName;
private readonly GoogleCredential _credential;
private readonly UrlSigner _urlSigner;
public StorageController(GoogleCredential credential, string bucketName)
{
_credential = credential;
_bucketName = bucketName;
_urlSigner = UrlSigner.FromServiceAccountCredential(_credential.UnderlyingCredential as ServiceAccountCredential);
}
[HttpGet("download/{file}")]
public async Task DownloadFileAsync(string file)
{
using var storageClient = await StorageClient.CreateAsync(_credential);
var signUrl = await _urlSigner.SignAsync(
_bucketName,
file,
TimeSpan.FromHours(3),
HttpMethod.Get
);
await this.HttpProxyAsync(signUrl);
}
}
}
I'm trying to retrofit MSI to an existing app.
The original app's DbContext used only a Constructor that found a ConnectionString by the same name in the web.config.
I've modified it to use a DbConnectionFactory to inject an AccessToken.
public class AppCoreDbContext : DbContext {
public AppCoreDbContext() : this("AppCoreDbContext")
{
}
public AppCoreDbContext(string connectionStringOrName) : base( OpenDbConnectionBuilder.Create(connectionStringOrName).Result, true)
{
}
...etc...
}
The class that it is invoking looks like:
public static class OpenDbConnectionBuilder
{
public static async Task<DbConnection> CreateAsync(string connectionStringName)
{
var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
var dbConnection = DbProviderFactories
.GetFactory(connectionStringSettings.ProviderName)
.CreateConnection();
dbConnection.ConnectionString = connectionStringSettings.ConnectionString;
await AttachAccessTokenToDbConnection(dbConnection);
// Think DbContext will open it when first used.
//await dbConnection.OpenAsync();
return dbConnection;
}
static async Task AttachAccessTokenToDbConnection(IDbConnection dbConnection)
{
SqlConnection sqlConnection = dbConnection as SqlConnection;
if (sqlConnection == null)
{
return;
}
string msiEndpoint = Environment.GetEnvironmentVariable("MSI_ENDPOINT");
if (string.IsNullOrEmpty(msiEndpoint))
{
return;
}
var msiSecret = Environment.GetEnvironmentVariable("MSI_SECRET");
if (string.IsNullOrEmpty(msiSecret))
{
return;
}
string accessToken = await AppCoreDbContextMSITokenFactory.GetAzureSqlResourceTokenAsync();
sqlConnection.AccessToken = accessToken;
}
}
Which invokes
// Refer to: https://winterdom.com/2017/10/19/azure-sql-auth-with-msi
public static class AppCoreDbContextMSITokenFactory
{
private const String azureSqlResource = "https://database.windows.net/";
public static async Task<String> GetAzureSqlResourceTokenAsync()
{
var provider = new AzureServiceTokenProvider();
var result = await provider.GetAccessTokenAsync(azureSqlResource);
return result;
}
}
The result of the above is that when tracking it with a debugger, it gets to
var result = await provider.GetAccessTokenAsync(azureSqlResource);
then hangs for ever.
Note: I'm working on a personal machine, not joined to the organisation domain -- but my personal MSA has been invited to the organisation's domain.
Admittedly, I've taken a hiatus from development for a couple of years, and the hang is probably due to having made a mistake around await (always been rough on understanding that implicitly)... but while trying to figure that out, and the documentation is pretty sparse, would appreciate feedback as to whether the above was the intended approach for using MSI.
I'm wondering:
When deploying to Azure, we can tell the ARM to create the Identity -- when developing, how do we tell the local machine to use MSI?
If on the dev machine the connection string is to a local db, and I create and add the token anyway, will it ignore it, or raise an exception.
This is a bit beyond the scope of discussing MSI, but I've never before created a dbConnection to use within a DbContext. Does anyone know the pros/cons of the DbContext 'owning' the connection? I'm assuming that it would be wiser to own & close the connection when the dbcontext is closed.
Basically...this is all new, so would appreciate any advice on getting this working -- the concept of being able to deploy without secrets would be awesome and would really like to get this demo working.
Thanks very much!
Hello user9314395: Managed Service Identity only works with resources running on Azure. While we don't support the local development scenario, you might consider looking into using the following (preview) library: https://learn.microsoft.com/en-us/azure/key-vault/service-to-service-authentication
I have a requirement, at least for now, to create a subdirectory based on a username for a .NET Core website. Where is the best place to do this?
I tried adding in ApplicationUser and I am not sure how to add it correctly. What I have, which I know is completely wrong, is the following.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using System.IO;
namespace BRSCRM.Models
{
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
private IHostingEnvironment hostingEnvironment;
public string HomeDir { get; set; }
HomeDir=HostingEnvironment.WebRootPath + UserName;
string path = this.hostingEnvironment.WebRootPath + "\\uploads\\" + UserName;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}
I wish the documentation was better. It seems they have plenty of getting-started material out there, but when you go to try and do something that is not covered it gets pretty tough to find help.
What I am trying to do is supportfileuploading for members.
I think I am getting closer, but I get this error now:
> 'Microsoft.AspNetCore.Hosting.IHostingEnvironment'. Model bound complex types must not be abstract or value types and must have a parameterless constructor Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel(ModelBindingContext
I cannot seem to read the IHostingEnvironment webrootpath. It is so frustrating!!
I moved my code into the Register action in file AccountController.cs...
This is what I have so far..
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, "Member");
_logger.LogInformation("User created a new account with password.");
// Add code here to create a directory...
string webRootPath = _hostingEnvironment.WebRootPath;
string contentRootPath = _hostingEnvironment.ContentRootPath;
var userId = User.FindFirstValue(ClaimTypes.Email);
string path = webRootPath + "\\uploads\\" + userId;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
I removed the code for the environment since it didn’t work anyway. I tried to just add a directory on my local system, but I discovered that I am not getting anything in the claims field. I am not sure how to get the username, email or anything else out of it. What should I do?
The code is 1) syntactically and 2) ideologically incorrect.
The following code must be in some method, not in the model class definition
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
The main idea of MVC is to separate the model definition (M), business logic (controller C), and presentation (view V). So a part of the code should be in some controller where the folder is first required (for example, AccountController) and called from (for example) [HttpPost]Register action.
private void SetUserFolder(ApplicationUser user)
{
IHostingEnvironment hostingEnvironment = /*getEnv()*/;
user.HomeDir = HostingEnvironment.WebRootPath + user.UserName;
string path = this.hostingEnvironment.WebRootPath + "\\uploads\\" + UserName;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}
Would it meet your requirements to just check if the folder exists when the user uploads a file, then create it before saving the file if it doesn't?
As an example, if your action method (assuming MVC) is like so:
Upload files in ASP.NET Core
[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
long size = files.Sum(f => f.Length);
// Full path to file in temp location
var filePath = Path.GetTempFileName();
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
// Process uploaded files
// Don't rely on or trust the FileName property without validation.
return Ok(new { count = files.Count, size, filePath});
}
You could simply use your own path in place of
var filePath = Path.GetTempFileName();
and check for its existence/create it if needed before saving.
I am trying to load a DLL from internet, more specifically it is Azure storage (Blob), so I used "Assembly.UnsafeLoadFrom" like this:
Assembly.UnsafeLoadFrom(#"https://accountname.blob.core.windows.net/test/calculator.dll");
But becuaset this specific call, my web app (published) returns:
"The specified CGI application encountered an error and the server
terminated the process."
The weird part is if I am using my local build, it is fine. there is no crash and the return result is correct.
I am using Visual Studio 2015 and .net 5.
Please let me know how to resolve this issue or how to debug it.
Thanks
For a simple way, you could achieve your purpose by the following code:
calculator.dll
public class Calculator
{
public string HelloWorld(string userName)
{
return string.Format("Hello world, {0}!", userName);
}
}
HomeController.cs
public async Task<ActionResult> Index()
{
string url = "https://brucechen.blob.core.windows.net/dll/calculator.dll";
HttpClient client = new HttpClient();
var bytes = await client.GetByteArrayAsync(url);
//load assembly from bytes
Assembly assembly = Assembly.Load(bytes);
var calc = assembly.CreateInstance("calculator.Calculator");
//invoke the method and get result
var result = calc.GetType().InvokeMember("HelloWorld", BindingFlags.InvokeMethod, null, calc, new[] { "Bruce" });
ViewData["result"] = result;
return View();
}
Result