the type or namespace name 'httpcontext 'does not exist in the namespace system.web(are you missing an assembly reference ) - asp.net

I got an error like this when trying to add google drive service to my project. Although there is "System.Web" in the "Library" section, it cannot be used actively. Could you help?
public static string DownloadGoogleFile(string fileId)
{
DriveService service = GetService();
string FolderPath = System.Web.HttpContext.Current.Server.MapPath("/GoogleDriveFiles/");
FilesResource.GetRequest request = service.Files.Get(fileId);
string FileName = request.Execute().Name;
string FilePath = System.IO.Path.Combine(FolderPath, FileName);
MemoryStream stream1 = new MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
SaveStream(stream1, FilePath);
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
break;
}
}
};
request.Download(stream1);
return FilePath;
}

Trying to pass the current HttpContext to a static method gets tricky depending on the project framework. It's also not clear the type of project or framework you are using.
Here's a similar question that might help you clarify the difference between HttpContext when it pertains to .net and .net-core.
HttpContext in .net standard library

Related

Make ASP.NET Core server (Kestrel) case sensitive on Windows

ASP.NET Core apps running in Linux containers use a case sensitive file system, which means that the CSS and JS file references must be case-correct.
However, Windows file system is not case sensitive. Therefore during development you can have CSS and JS files referenced with incorrect casing, and yet they work fine. So you won't know during development on Windows, that your app is going to break when going live on Linux servers.
Is there anyway to make Kestrel on Windows case sensitive, so that we can have consistent behaviour and find the reference bugs before going live?
I fixed that using a middleware in ASP.NET Core.
Instead of the standard app.UseStaticFiles() I used:
if (env.IsDevelopment()) app.UseStaticFilesCaseSensitive();
else app.UseStaticFiles();
And defined that method as:
/// <summary>
/// Enforces case-correct requests on Windows to make it compatible with Linux.
/// </summary>
public static IApplicationBuilder UseStaticFilesCaseSensitive(this IApplicationBuilder app)
{
var fileOptions = new StaticFileOptions
{
OnPrepareResponse = x =>
{
if (!x.File.PhysicalPath.AsFile().Exists()) return;
var requested = x.Context.Request.Path.Value;
if (requested.IsEmpty()) return;
var onDisk = x.File.PhysicalPath.AsFile().GetExactFullName().Replace("\\", "/");
if (!onDisk.EndsWith(requested))
{
throw new Exception("The requested file has incorrect casing and will fail on Linux servers." +
Environment.NewLine + "Requested:" + requested + Environment.NewLine +
"On disk: " + onDisk.Right(requested.Length));
}
}
};
return app.UseStaticFiles(fileOptions);
}
Which also uses:
public static string GetExactFullName(this FileSystemInfo #this)
{
var path = #this.FullName;
if (!File.Exists(path) && !Directory.Exists(path)) return path;
var asDirectory = new DirectoryInfo(path);
var parent = asDirectory.Parent;
if (parent == null) // Drive:
return asDirectory.Name.ToUpper();
return Path.Combine(parent.GetExactFullName(), parent.GetFileSystemInfos(asDirectory.Name)[0].Name);
}
Based on #Tratcher proposal and this blog post, here is a solution to have case aware physical file provider where you can choose to force case sensitivity or allow any casing regardless of OS.
public class CaseAwarePhysicalFileProvider : IFileProvider
{
private readonly PhysicalFileProvider _provider;
//holds all of the actual paths to the required files
private static Dictionary<string, string> _paths;
public bool CaseSensitive { get; set; } = false;
public CaseAwarePhysicalFileProvider(string root)
{
_provider = new PhysicalFileProvider(root);
_paths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public CaseAwarePhysicalFileProvider(string root, ExclusionFilters filters)
{
_provider = new PhysicalFileProvider(root, filters);
_paths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IFileInfo GetFileInfo(string subpath)
{
var actualPath = GetActualFilePath(subpath);
if(CaseSensitive && actualPath != subpath) return new NotFoundFileInfo(subpath);
return _provider.GetFileInfo(actualPath);
}
public IDirectoryContents GetDirectoryContents(string subpath)
{
var actualPath = GetActualFilePath(subpath);
if(CaseSensitive && actualPath != subpath) return NotFoundDirectoryContents.Singleton;
return _provider.GetDirectoryContents(actualPath);
}
public IChangeToken Watch(string filter) => _provider.Watch(filter);
// Determines (and caches) the actual path for a file
private string GetActualFilePath(string path)
{
// Check if this has already been matched before
if (_paths.ContainsKey(path)) return _paths[path];
// Break apart the path and get the root folder to work from
var currPath = _provider.Root;
var segments = path.Split(new [] { '/' }, StringSplitOptions.RemoveEmptyEntries);
// Start stepping up the folders to replace with the correct cased folder name
for (var i = 0; i < segments.Length; i++)
{
var part = segments[i];
var last = i == segments.Length - 1;
// Ignore the root
if (part.Equals("~")) continue;
// Process the file name if this is the last segment
part = last ? GetFileName(part, currPath) : GetDirectoryName(part, currPath);
// If no matches were found, just return the original string
if (part == null) return path;
// Update the actualPath with the correct name casing
currPath = Path.Combine(currPath, part);
segments[i] = part;
}
// Save this path for later use
var actualPath = string.Join(Path.DirectorySeparatorChar, segments);
_paths.Add(path, actualPath);
return actualPath;
}
// Searches for a matching file name in the current directory regardless of case
private static string GetFileName(string part, string folder) =>
new DirectoryInfo(folder).GetFiles().FirstOrDefault(file => file.Name.Equals(part, StringComparison.OrdinalIgnoreCase))?.Name;
// Searches for a matching folder in the current directory regardless of case
private static string GetDirectoryName(string part, string folder) =>
new DirectoryInfo(folder).GetDirectories().FirstOrDefault(dir => dir.Name.Equals(part, StringComparison.OrdinalIgnoreCase))?.Name;
}
Then in Startup class, make sure you register a provider for content and web root as follow:
_environment.ContentRootFileProvider = new CaseAwarePhysicalFileProvider(_environment.ContentRootPath);
_environment.WebRootFileProvider = new CaseAwarePhysicalFileProvider(_environment.WebRootPath);
It was possible in Windows 7 but not windows 10 and as far as I can tell, it's also not possible on Windows Server at all.
I can only talk about the OS because the Kestrel documentation says:
The URLs for content exposed with UseDirectoryBrowser and UseStaticFiles are subject to the case sensitivity and character restrictions of the underlying file system. For example, Windows is case insensitive—macOS and Linux aren't.
I'd recommend a convention for all filenames ("all lowercase" usually works best). And to check for inconsistencies, you can run a simple PowerShell script that uses regular expressions to check for wrong casing. And that script can be put on a schedule for convenience.

JxBrowser not connecting

I am having troubles to make the jxbrowser work outside of the development environment. When I run it in eclipse it works fine, but when I compile it and run the screen doesn't seems to load. Here is the code that I'm using:
browser = new Browser();
com.teamdev.jxbrowser.chromium.swing.BrowserView view = new com.teamdev.jxbrowser.chromium.swing.BrowserView(browser);
javax.swing.JFrame frame = new javax.swing.JFrame();
frame.add(view, java.awt.BorderLayout.CENTER);
frame.setSize(800, 450);
frame.setVisible(true);
browser.loadURL(Main.class.getResource("/assets/engine.html").toExternalForm());
> When I run from eclipse <
> When I compile and run <
Am I missing something?
If your HTML resource "/assets/engine.html" is located inside the RPGItems.jar after build, the path to it will not be resolved properly by the Chromium engine by default. To be able to load resources located inside JAR archive you must register custom ProtocolHandler with the following implementation:
BrowserContext browserContext = browser.getContext();
ProtocolService protocolService = browserContext.getProtocolService();
protocolService.setProtocolHandler("jar", new ProtocolHandler() {
#Override
public URLResponse onRequest(URLRequest request) {
try {
URLResponse response = new URLResponse();
URL path = new URL(request.getURL());
InputStream inputStream = path.openStream();
DataInputStream stream = new DataInputStream(inputStream);
byte[] data = new byte[stream.available()];
stream.readFully(data);
response.setData(data);
String mimeType = getMimeType(path.toString());
response.getHeaders().setHeader("Content-Type", mimeType);
return response;
} catch (Exception ignored) {}
return null;
}
});
The getMimeTypemethod here returns appropriate mime type for the given resource extension:
private static String getMimeType(String path) {
if (path.endsWith(".html")) {
return "text/html";
}
if (path.endsWith(".css")) {
return "text/css";
}
if (path.endsWith(".js")) {
return "text/javascript";
}
return "text/html";
}
Once you register ProtocolHandler and define what mime types are supported, you can load resources from JAR archive using standard Java and JxBrowser API:
browser.loadURL(Main.class.getResource("/assets/engine.html").toString());

NSUrl Not Initializing properly

I've placed 25 mp3 files in the "Music folder" in my Xamarin.ios project.
I called the Play function and passed in the name of a mp3 file I want to play. I created a string object which contains the filePath.
Then I create a another string object called "withFileName" containing the path and song name passed into the function. The withFileName variable looks correct.
When I execute the instruction ...
songURL = new NSUrl(withFileName);
I get the following exception...
System.Exception: Could not initialize an instance of the type 'Foundation.NSUrl': the native 'initWithString:' method returned nil. It is possible to ignore this condition by setting MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure to false. at Foundation.NSO…
I'm lost, need some help.
code snippet:
public void Play(String song)
{
String dir = Directory.GetCurrentDirectory();
String filePath = Path.Combine(dir, "Music");
String withFileName = String.Format("{0}/{1}", filePath, song);
NSUrl songURL = null;
try
{
songURL = new NSUrl(withFileName);
}
catch (Exception e)
{
string msg = e.Message;
}
NSError err;
_audioPlayer = new AVAudioPlayer( songURL,"Song", out err );
_audioPlayer.Play();
}
It seems You can get the correct path of file embeded in the project. Then if you want to get the file's url you should use:
new NSUrl(filePath, false);
//or
NSUrl.FromFilename(filePath)

ASP.NET Core RC-1 file upload

I am currently uploading a file via the kendo fileuploader to an api controller using ASP.NET core RC-1. I am receiving a periodic error of "object reference not set to instance of object" when attempting to read the stream following opening the stream with IFormFile.OpenReadStream().
My controller is:
[HttpPost]
[Route("api/{domain}/[controller]")]
public async Task<IActionResult> Post([FromRoute]string domain, [FromForm]IFormFile file, [FromForm]WebDocument document)
{
if (ModelState.IsValid)
{
if (file.Length > 0)
{
var userName =
Request.HttpContext.User.Claims
.FirstOrDefault(c => c.Type == ClaimTypesEx.FullName)?
.Value;
var uploadedFileName =
ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
document.Domain = domain;
document.MimeType = file.ContentType;
document.SizeInBytes = file.Length;
document.ChangedBy = userName;
document.FileName = (string.IsNullOrEmpty(document.FileName)) ? uploadedFileName : document.FileName;
try
{
document = await CommandStack.For<WebDocument>()
.AddOrUpdateAsync(document, file.OpenReadStream()).ConfigureAwait(false);
}
catch (Exception e)
{
return new HttpStatusCodeResult(500);
}
return Ok(document);
}
}
return new BadRequestResult();
}
And the error is being thrown when I actually try to read the stream when it is going into blob storage:
public async Task<Uri> CreateOrUpdateBlobAsync(string containerName, string fileName, string mimeType,
Stream fileStream)
{
var container = Client.GetContainerReference(containerName);
var blob = container.GetBlockBlobReference(fileName);
//Error HERE
await blob.UploadFromStreamAsync(fileStream);
blob.Properties.ContentType = mimeType;
await blob.SetPropertiesAsync();
return blob.Uri;
}
What I am having trouble with is this is sporadic and there seems to be no defined pattern of which files are accepted and which ones generate the error. At first I thought it might be a size issue but that is not the case as I have several larger files uploaded successfully and then one small file will throw the error. Images seem to work fine and it is hit or miss on other file types with no rhyme or reason that I can figure out.

Windows Phone 8 Hanging on GetFolderAsync and OpenStreamForReadAsync

I am making a windows phone 8 application. Part of this application requires state to be saved. I am saving it as a string of Json. If I open the application, save some data, exit the application and the load it again, it hangs on either GetFolderAsync or OpenStreamForReadAsync. It does not happen every time, but once it starts hanging, I have to kill the whole emulator and make a new one to start the application again.
I have even tried just making an empty file with no data in it and the problem still persistes.
Below is the code I am using to save and load the data. It does not matter where I call the data load whether it be on application start or on the form load it still breaks.
private async Task SaveLists()
{
//XmlSerializer serializer = new XmlSerializer(typeof(ListHolder));
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name DataFolder.
var dataFolder = await local.CreateFolderAsync("DataFolder",
CreationCollisionOption.OpenIfExists);
// Create a new file named DataFile.txt.
var file = await dataFolder.CreateFileAsync("Lists.json",
CreationCollisionOption.ReplaceExisting);
string json = JsonConvert.SerializeObject(Lists, Formatting.Indented);
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(json.ToCharArray());
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
private async Task LoadLists()
{
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
try
{
// Get the DataFolder folder.
var dataFolder = await local.GetFolderAsync("DataFolder");
// Get the file.
var files = dataFolder.GetFilesAsync();
var file = await dataFolder.OpenStreamForReadAsync("Lists.json");
string jsonString = "";
// Read the data.
using (StreamReader streamReader = new StreamReader(file))
{
jsonString = streamReader.ReadToEnd();
}
if (jsonString.Length > 0)
{
Lists = JsonConvert.DeserializeObject<List<ItemList>>(jsonString);
}
else
{
Lists = new List<ItemList>();
}
}
catch (Exception ex)
{
Lists = new List<ItemList>();
}
}
}
You are causing a deadlock by calling Result. I explain this deadlock on my blog and in a recent MSDN article. In summary, await will (by default) attempt to resume execution within a context (the current SynchronizationContext unless it is null, in which case it uses the current TaskScheduler).
In your case, the current SynchronizationContext is the UI context, which is only used by the UI thread. So when you block the UI thread by calling Result, the async method cannot schedule back to the UI thread to complete.

Resources