I am working on a project to get text from this website.
But when I tested it in Visual Studio, I've got some error:
Value cannot be null. Parameter name: solutionDirectory
Here is my code:
using System;
using System.Net;
public class Program
{
public static void Main()
{
WebClient client = new WebClient();
String temp = client.DownloadString("http://www.hkex.com.hk/eng/stat/dmstat/dayrpt/hsio180629.htm");
Console.Write(temp);
}
}
Please use HttpClient Which is very good Option Compare to webClient
And your problem is sounds like your project (vcxproj) file isn't setup properly.
So create New Application Simply and run this Code.
Here you find Actually Difference
Stream client = Task.Run(()=>new HttpClient().GetAsync("http://www.hkex.com.hk/eng/stat/dmstat/dayrpt/hsio180629.htm").Result.Content.ReadAsStreamAsync()).Result;
using (var fileStream = new FileStream("D://data.txt", FileMode.Create, FileAccess.Write))
{
client.CopyTo(fileStream);
}
Full Working Code:-
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Stream client = Task.Run(()=>new HttpClient().GetAsync("http://www.hkex.com.hk/eng/stat/dmstat/dayrpt/hsio180629.htm").Result.Content.ReadAsStreamAsync()).Result;
using (var fileStream = new FileStream("D://data.txt", FileMode.Create, FileAccess.Write))
{
client.CopyTo(fileStream);
}
}
}
}
With Await
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
data();
Console.ReadKey();
}
public static async void data()
{
var client = await new HttpClient().GetAsync("http://www.hkex.com.hk/eng/stat/dmstat/dayrpt/hsio180629.htm");
var data= await client.Content.ReadAsStreamAsync();
using (var fileStream = new FileStream("D://data.txt", FileMode.Create, FileAccess.Write))
{
data.CopyTo(fileStream);
}
}
}
}
Related
I have a serializable class in some library assembly.
also I have to projects referencing this assembly.
One project serializes an instance of my class,
other project serializes this instance of my class.
I copied dll of this assembly into some backup folder to get ability to restore an old version.
I added new field in my class.
I serialized an instance of my updated class.
Then I restored old version of my class and deserialized the instance.
BinaryFormatter works well and doesn't throw an exception.
Do we need an [optionalField] attribute?
Library
using System;
namespace SerializationFramework
{
[Serializable]
public class MyClass
{
public string Field { get; set; }
//public string NewField { get; set; }//added in Version 2, without [OptionalField] attribute
public MyClass()
{
Field = "test";
//NewField = "newField";
}
//for checking versions
public void Test()
{
Console.WriteLine("Version 1");//comment after adding a new field
//Console.WriteLine("Version 2");//uncomment after adding a new field
Console.ReadLine();
}
}
}
Serializing
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using SerializationFramework;
namespace Serialization
{
class Program
{
static void Main(string[] args)
{
var binaryF = new BinaryFormatter();
var obj = new MyClass();
using (var f = File.Create(#"C:\temp\oleg.txt"))
{
binaryF.Serialize(f, obj);
}
Console.WriteLine("Serialized!");
Console.ReadLine();
}
}
}
Deserializing
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using SerializationFramework;
namespace Deserialization
{
class Program
{
static void Main(string[] args)
{
var binaryF = new BinaryFormatter();
MyClass obj;
using (var f = File.Open(#"c:\temp\oleg.txt", FileMode.Open))
{
obj = (MyClass) binaryF.Deserialize(f);
}
//CheckingVersion
var obj2 = new MyClass();
obj2.Test();
}
}
}
I am trying to add support for System.Web.Mvc.HtmlHelper to a CLI app for compiling Razor templates, but although it compiles it fails at runtime with:
System.TypeLoadException: Could not load type 'HtmlHelper`1' from assembly '/Users/oligofren/src/razor-cli/build/System.Web.Mvc.dll'.
How should I proceed in fixing this?
I am not well versed in the core of .NET (here in Mono version), so I can't say if I have done anything wrong here. I have added all the assemblies to the build folder (where the exe ends up) and I also try to manually load the required assemblies before RazorEngine tries to compile the assemblies.
How can I resolve this?
Full source code
// See also tips on building cli apps with razorengine: https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Hosts.Console/RazorEngine.Hosts.Console.csproj
using System;
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;
using Moq;
using System.IO;
using Newtonsoft.Json.Linq;
using RazorEngine;
using RazorEngine.Templating; // For extension methods.
using RazorEngine.Configuration;
using RazorEngine.Text;
public class RazorCli
{
static public void Main (string[] args)
{
CheckCommandLine(args);
string template = ReadFile(args[0]);
JObject model = ParseModel(args[1]);
// try to load the required assemblies
//http://stackoverflow.com/a/23496144/200987
System.Reflection.Assembly.Load("System.Web");
System.Reflection.Assembly.Load("System.Web.Mvc");
var result = CompileTemplate(template, model);
Console.WriteLine (result);
}
private static string CompileTemplate (string template, JObject model)
{
string res = "";
var config = new TemplateServiceConfiguration();
// You can use the #inherits directive instead (this is the fallback if no #inherits is found).
config.BaseTemplateType = typeof(MyClassImplementingTemplateBase<>);
try
{
using (var service = RazorEngineService.Create(config))
{
res = service.RunCompile(template, "templateKey", null, model);
}
}
catch( RazorEngine.Templating.TemplateCompilationException ex )
{
Console.WriteLine (ex);
System.Environment.Exit(1);
}
return res;
}
/* Cannot dispatch a dynamic object to extension methods */
private static JObject ParseModel(string fileName){
string json = ReadFile(fileName);
return JObject.Parse(json);
}
private static void CheckCommandLine(string[] args){
if(args.Length != 2){
Usage();
System.Environment.Exit(1);
}
}
private static void Usage(){
string usage = "Usage: razor-cli <partial.cshtml> <model.json>\n";
Console.WriteLine(usage);
}
private static String ReadFile(string filename)
{
string result;
using (StreamReader sr = new StreamReader(filename))
{
result = sr.ReadToEnd();
}
return result;
}
}
public class MyHtmlHelper
{
public IEncodedString Raw(string rawString)
{
return new RawString(rawString);
}
}
// https://antaris.github.io/RazorEngine/TemplateBasics.html
public abstract class MyClassImplementingTemplateBase<T> : TemplateBase<T>
{
public MyClassImplementingTemplateBase()
{
Html = MvcHelpers.CreateHtmlHelper<Object>();
}
public HtmlHelper Html { get; set; }
}
// Ripped straight from a SO Q/A
// http://stackoverflow.com/questions/17271688/mocking-viewcontext-to-test-validation-error-messages
public class MvcHelpers {
public static HtmlHelper<TModel> CreateHtmlHelper<TModel>(ViewDataDictionary dictionary = null)
{
if (dictionary == null)
dictionary = new ViewDataDictionary { TemplateInfo = new TemplateInfo() };
var mockViewContext = new Mock<ViewContext>(
new ControllerContext(
new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object),
new Mock<IView>().Object,
dictionary,
new TempDataDictionary(),
new Mock<TextWriter>().Object);
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData).Returns(dictionary);
return new HtmlHelper<TModel>(mockViewContext.Object, mockViewDataContainer.Object);
}
}
Details on how I run this can be seen in the Makefile, if that helps.
Further details
Installed Mono 4.2.2.0 using Homebrew on OS X 10.11.4.
I tried XML serialization the first time. The following code works as expected, but I don't like to use this "copyFrom" method.
Is there a better way that keeps the save and load methods inside the class itself?
namespace Test
{
[Serializable]
public class Settings
{
public struct Connection
{
[XmlAttribute ("user")]
public string sUser;
[XmlAttribute ("domain")]
public string sDomain;
}
public Connection connection;
public Settings ()
{
connection.sUser = "";
connection.sDomain = "";
}
internal void loadFromFile ()
{
if (File.Exists (Constants.STORAGE_SETTINGS_FILE))
{
using (FileStream filestream = new FileStream (Constants.STORAGE_SETTINGS_FILE, FileMode.Open, FileAccess.Read, FileShare.Read))
{
copyFrom ((Settings)new XmlSerializer (typeof (Settings)).Deserialize (filestream));
}
}
}
internal void saveToFile ()
{
using (StreamWriter streamwriter = new StreamWriter (Constants.STORAGE_SETTINGS_FILE))
{
new XmlSerializer (typeof (Settings)).Serialize (streamwriter, this);
}
}
internal void copyFrom (Settings settings)
{
connection.sUser = settings.connection.sUser;
connection.sDomain = settings.connection.sDomain;
}
}
}
You can remove copyFrom method.
In the loadFromFile method, you can write
connection = ((Settings)new XmlSerializer(typeof(Settings)).Deserialize(filestream)).connection;
Also note that the Serializable attribute not needed for XML serialization. Remove it.
I have a system that is supposed to write lines to a HTTP response stream. Each line in this system represents some kind of event, so you can see this as a notification stream. I am using .NET4 on Windows 7 using NancyFX and Nancy self hosting (0.23). The following code is functional:
using System;
using System.IO;
using System.Threading;
using Nancy;
using Nancy.Hosting.Self;
namespace TestNancy
{
public class ChunkedResponse : Response
{
public ChunkedResponse()
{
ContentType = "text/html; charset=utf-8";
Contents = stream =>
{
using (var streamWriter = new StreamWriter(stream))
{
while (true)
{
streamWriter.WriteLine("Hello");
streamWriter.Flush();
Thread.Sleep(1000);
}
}
};
}
}
public class HomeModule : NancyModule
{
public HomeModule()
{
Get["/"] = args => new ChunkedResponse();
}
}
public class Program
{
public static void Main()
{
using (var host = new NancyHost(new Uri("http://localhost:1234")))
{
host.Start();
Console.ReadLine();
}
}
}
}
Now I want to add compression to the stream to compress the amount of bandwidth. For some reason, when testing in a browser, I cannot see any result whatsoever. I have tried a lot of combinations to achieve the desired result, but this is what I have at the moment:
using System; using System.IO; using System.IO.Compression; using System.Threading; using Nancy; using Nancy.Hosting.Self;
namespace TestNancy {
public class ChunkedResponse : Response
{
public ChunkedResponse()
{
Headers["Content-Encoding"] = "gzip";
ContentType = "text/html; charset=utf-8";
Contents = stream =>
{
using (var gzip = new GZipStream(stream, CompressionMode.Compress))
using (var streamWriter = new StreamWriter(gzip))
{
while (true)
{
streamWriter.WriteLine("Hello");
streamWriter.Flush();
Thread.Sleep(1000);
}
}
};
}
}
public class HomeModule : NancyModule
{
public HomeModule()
{
Get["/"] = args => new ChunkedResponse();
}
}
public class Program
{
public static void Main()
{
using (var host = new NancyHost(new Uri("http://localhost:1234")))
{
host.Start();
Console.ReadLine();
}
}
} }
I am looking for help that either tells me what I am doing wrong concerning the HTTP protocol (e.g. I tried adding chunk lengths as described in HTTP1.1, which did not work), or help concerning Nancy where it does something I did not account for.
The problem seems to be in Gzip implementation of the framework as it never writes to output stream before getting closed,
I simply used SharpZiplib and your code seems to work for me, here is my modifications
public class ChunkedResponse : Response
{
public ChunkedResponse()
{
Headers["Transfer-Encoding"] = "chunked";
Headers["Content-Encoding"] = "gzip";
ContentType = "text/html; charset=utf-8";
Contents = stream =>
{
var gzip = new ICSharpCode.SharpZipLib.GZip.GZipOutputStream(stream);
using (var streamWriter = new StreamWriter(gzip))
{
while (true)
{
streamWriter.WriteLine("Hello");
gzip.Flush();
streamWriter.Flush();
Thread.Sleep(1000);
}
}
};
}
}
public class HomeModule : NancyModule
{
public HomeModule()
{
Get["/"] = args => new ChunkedResponse();
}
}
public class Program
{
public static void Main()
{
using (var host = new NancyHost(new HostConfiguration{AllowChunkedEncoding = true},new Uri("http://localhost:1234")))
{
host.Start();
Console.ReadLine();
}
}
}
Nuget package for SharpZipLib: PM> Install-Package SharpZipLib
It looks as though whatever calls the delegate you supply as ChunkedReponse.Contents will never return because of the while(true). Is this intended behaviour? Not knowing what this framework does with that delegate, I couldn't guess.
At first glance I did wonder whether the constructor would never return - which I guess would definitely cause a problem - but it didn't take me long to notice that it's a lambda. Fortunately.
Edit #1:
The documentation for GZipStream.Flush() says:
The current implementation of this method has no functionality.
(Overrides Stream.Flush().)
This implies to me that GZipStream doesn't write anything to the transport until it's closed. Do you experience different behaviour if you don't run the mentioned delegate forever, and instead close the stream at some point?
I have tested it myself and I think the problem is how the browser handles these chunked and compressed responses. This is what I tried and what basically worked:
Contents = stream =>
{
using (var gzip = new GZipStream(stream, CompressionMode.Compress))
using (var streamWriter = new StreamWriter(gzip))
{
for (int i = 0; i < 5;i++ )
{
string txt = "Hello";
streamWriter.WriteLine(txt);
streamWriter.Flush();
Thread.Sleep(1000);
}
}
};
The problem is that the browser waits for the chunked response to be ready before it displays the result. It probably waits with decompression until all data has been sent, although gzip supports streaming. Here is a first hint that supports my assumption.
My program was practice for me, however, when I try to write all the directories it found, it crashes.
I tried the following:
Having it write to a file stream instead of the file itself
using File.Writealllines using a list<> (this worked, only it did the first five and no more)
FileStream.Write(subdir.ToCharArray())
I cannot see why this wouldn't work, what have I done wrong?
static void Main(string[] args)
{
Method(#"C:\");
}
static void Method(string dir)
{
//crash happens here v
StreamWriter sw = new StreamWriter(#"C:\users\"+Environment.UserName+"\desktop\log.txt",true);
foreach (string subdir in Directory.GetDirectories(dir))
{
try
{
Console.WriteLine(subdir);
sw.Write(subdir);
Method(subdir);
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Error");
}
}
sw.Close();
}
Its recursive.
Because you're calling Method again here:
Console.WriteLine(subdir);
sw.Write(subdir);
Method(subdir); // BOOM
Your file is already open. You can't open it for writing again.
Open the file in Main once..
static void Main(string[] args) {
using (StreamWriter sw = new StreamWriter(#"C:\users\"+Environment.UserName+"\desktop\log.txt",true)) {
Method(#"C:\", sw);
}
}
Then accept it in your method:
public static void Method(string dir, StreamWriter sw) {
Then when you call it again:
sw.Write(subdir);
Method(subdir, sw); // pass in the streamwriter.
Note though, that you will quickly start chewing up memory. You're recursing through your entire C:\ drive. Maybe test it on a smaller folder?
I am agree with above but in my case solution different a little.
private static object locker = new object();
private static void WriteMessageToFile(string message)
{
string dateStr = DateTime.Now.Date.Day.ToString()+"_"+ DateTime.Now.Date.Month.ToString()+"_"+ DateTime.Now.Date.Year.ToString();
if (!Directory.Exists("Logs"))
{
DirectoryInfo di = Directory.CreateDirectory("Logs");
}
//Guid guidGenerator = Guid.NewGuid();
string filePath = _env.ContentRootPath + "\\Logs\\ProcessLog_" + dateStr + ".txt";
FileInfo fi = new FileInfo(filePath);
lock (locker)
{
using (FileStream file = new FileStream(fi.FullName, FileMode.Append, FileAccess.Write, FileShare.Read))
using (StreamWriter streamWriter = new StreamWriter(file))
{
streamWriter.WriteLine(message);
streamWriter.Close();
}
}
}
Because the following function is called asynchronous and asynchronous in many places in my asp.net core application. In this case, one thread was trying to write a file, another thread wanted to write the same file, and there was an error. As a solution, I tried the above, but it didn't work either because I tried to open a new stream before closing the previous stream. So I decided to write a secure block of code as a solution. In this case, since the other threads could not reach the locked area, they made the write operation by waiting for the previous operation and I was able to write the file without error.
I think; there is another reason code behind, cause i have used Singleton registration on startup. This function's caller classes are isolated from each other. with this reason they didn't know which thread is called the function before. Their lifetime has been finished while. Also FileStream wraps the StreamWriter then it also may work without lock, anyway it is guaranty.
Even Microsoft.Extensions.Logging does not support FileLoger by default, but we can write custom. I share the entire implementation below
public class FileLoger : ILogger
{
public static IHostingEnvironment _env;
private static object locker = new object();
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var message = string.Format("{0}: {1} - {2}", logLevel.ToString(), eventId.Id, formatter(state, exception));
WriteMessageToFile(message);
}
private static void WriteMessageToFile(string message)
{
string dateStr = DateTime.Now.Date.Day.ToString()+"_"+ DateTime.Now.Date.Month.ToString()+"_"+ DateTime.Now.Date.Year.ToString();
if (!Directory.Exists("Logs"))
{
DirectoryInfo di = Directory.CreateDirectory("Logs");
}
//Guid guidGenerator = Guid.NewGuid();
string filePath = _env.ContentRootPath + "\\Logs\\ProcessLog_" + dateStr + ".txt";
FileInfo fi = new FileInfo(filePath);
lock (locker)
{
using (FileStream file = new FileStream(fi.FullName, FileMode.Append, FileAccess.Write, FileShare.Read))
using (StreamWriter streamWriter = new StreamWriter(file))
{
streamWriter.WriteLine(message);
streamWriter.Close();
}
}
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
}
public class FileLogProvider : ILoggerProvider
{
public FileLogProvider(IHostingEnvironment env)
{
FileLoger._env = env;
}
public ILogger CreateLogger(string category)
{
return new FileLoger();
}
public void Dispose()
{
}
}
Seems you didn't close your streamwriter before you use it again
public static void Method(string dir)
{
//crash happens here v
StreamWriter sw = new StreamWriter(#"C:\users\"+Environment.UserName+"\desktop\log.txt",true);
foreach (string subdir in Directory.GetDirectories(dir))
{
try
{
Console.WriteLine(subdir);
sw.Write(subdir);
//This line you'll call "Method" again
Method(subdir);
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Error");
}
}
sw.Close();
}
Also, another suggestion, why don't you use "System.IO.File.AppendAllText(Path,Text)" method? it's easier to use