I have problem to call a method in a WCFService. I downladed the file below for a project and I want to call a method in SampleHttpResquestAndResponse class in my WCFService (Also, I tried to do it in a main method and i couldn't succeed it either). However I can't do it, i can't find the method when I type it. How to call those methods in SampleHttpResquestAndResponse class?
using System;
using System.IO;
using System.Net;
using System.Text;
using System.IO.Compression;
using System.Xml.Serialization;
namespace Sample
{
public class SampleHttpResquestAndResponse
{
/// <summary>
/// Adonis servisi ile iletişim kurmayı sağlar.
/// </summary>
/// <typeparam name="T">T</typeparam>
/// <param name="prm_ServiceName">string</param> SearchHotels // BasketHotels // ConfirmHotels
/// <param name="prm_Criteria">object</param>
/// <param name="prm_Url">string</param> "http://xmltest.adonis.com/AdonisServices"
/// <returns>T</returns>
public static T AdonisRequestResponseMethod<T>(string prm_ServiceName, object prm_Criteria, string prm_Url)
{
#region Variables
HttpWebRequest HttpWebRequest;
T ReturnValue;
#endregion
try
{
#region Xml Serializer
var XmlString = SampleHttpResquestAndResponse.ConvertTypeToXml<object>(prm_Criteria).ToString();
#endregion
#region Http Web Request
HttpWebRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}/{1}?prm_CurrentData={2}", prm_Url, prm_ServiceName, XmlString));
HttpWebRequest.ContentType = "text/xml;charset=\"utf-8\"";
HttpWebRequest.Method = "POST";
HttpWebRequest.Timeout = 80000000;
#endregion
#region Http Web Response
StreamWriter StreamWriterPost = new StreamWriter(HttpWebRequest.GetRequestStream());
StreamWriterPost.Write(XmlString);
StreamWriterPost.Close();
HttpWebResponse HttpWebResponse = (HttpWebResponse)HttpWebRequest.GetResponse();
StreamReader StreamReaderResponse = new StreamReader(HttpWebResponse.GetResponseStream(), Encoding.UTF8);
string StringResponse = string.Empty;
if (HttpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
{
using (GZipStream decompress = new GZipStream(HttpWebResponse.GetResponseStream(), CompressionMode.Decompress))
{
StreamReader reader = new StreamReader(decompress);
StringResponse = reader.ReadToEnd();
}
}
else
{
StreamReader reader = new StreamReader(HttpWebResponse.GetResponseStream(), Encoding.UTF8);
StringResponse = reader.ReadToEnd();
}
#endregion
#region Return Value Type Process (DESERIALIZE)
ReturnValue = SampleHttpResquestAndResponse.ConvertXmlToType<T>(StringResponse.ToString()).Data;
#endregion
#region Return Value
return ReturnValue;
#endregion
}
catch (Exception ex)
{
#region Return Value
return ReturnValue = SampleHttpResquestAndResponse.ConvertXmlToType<T>(ex.Message).Data;
#endregion
}
}
public static ResultDTO<T> ConvertXmlToType<T>(string prm_Xml)
{
#region Variables
T ReturnValue;
#endregion
try
{
#region Replace String Value
prm_Xml = prm_Xml.Replace("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
, "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
prm_Xml = prm_Xml.Replace("<", "<").Replace(">", ">").Replace(""", "\"");
#endregion
#region Deserialize
using (MemoryStream MemoryStream = new MemoryStream())
{
using (StreamWriter StreamWriter = new StreamWriter(MemoryStream))
{
StreamWriter.Write(prm_Xml);
StreamWriter.Flush();
MemoryStream.Position = 0;
XmlSerializer XmlSerializer = new XmlSerializer(typeof(T));
using (StreamReader StreamReader = new StreamReader(MemoryStream))
{
StreamReader.ReadLine();
#region Result Value (SET)
ReturnValue = (T)XmlSerializer.Deserialize(StreamReader);
#endregion
}
}
}
#endregion
#region Return Value
return new ResultDTO<T>
{
Data = ReturnValue,
Success = true
};
#endregion
}
catch (Exception ex)
{
#region Return Value
return new ResultDTO<T>
{
Success = false,
Message = string.Format("Error Type : {0} Code : {1} Method Name : {2} Error Mesage : {3}", "Undetermined", "1000", "ConvertXmlToType", ex.Message),
};
#endregion
}
}
public static string ConvertTypeToXml<T>(T prm_Criteria)
{
#region Variables
XmlSerializer XmlSerializer;
StringWriter StringWriter = new StringWriter();
#endregion
try
{
#region Xml Serializer
XmlSerializer = new XmlSerializer(prm_Criteria.GetType());
XmlSerializer.Serialize(StringWriter, prm_Criteria);
var XmlString = StringWriter.ToString();
#endregion
#region Request Replace
return XmlString = XmlString.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
#endregion
}
catch (Exception ex)
{
throw ex;
}
finally
{
GC.SuppressFinalize(StringWriter);
}
}
}
public class ResultDTO
{
#region Properties
/// <summary>
/// İslem durumu.
/// </summary>
public bool Success { get; set; }
/// <summary>
/// İşlem mesajı.
/// </summary>
public string Message { get; set; }
#endregion
}
public class ResultDTO<T> : ResultDTO
{
#region Fields
/// <summary>
/// Generic data tipi.
/// </summary>
private T data = Activator.CreateInstance<T>();
#endregion
#region Properties
/// <summary>
/// Generic data tipi
/// </summary>
public T Data
{
get
{
if (data == null)
return data = default(T);
return data;
}
set { data = value; }
}
#endregion
}
}
PS: I know it is a little bit silly question, but i couldn't figure it. If it is needed, the below is how i try to call any method in this class in a simple way
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.IO;
using System.Net;
using System.Text;
using System.IO.Compression;
using System.Xml.Serialization;
using Sample;
namespace Adonis
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "AdonisService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select AdonisService.svc or AdonisService.svc.cs at the Solution Explorer and start debugging.
public class AdonisService : IAdonisService
{
ResultDTO res = new ResultDTO();
SampleHttpResquestAndResponse samp = new SampleHttpResquestAndResponse();
public string results()
{
string a1 = "";
object c = new object();
c = 434;
string b = "";
string a = "";
a= samp.AdonisRequestResponseMethod(a, c, b);
}
}
}
AdonisRequestResponseMethod is static, and as such would be called like this:
SampleHttpResquestAndResponse.AdonisRequestResponseMethod(a, b, c);
However, it is also a generic method, so you will have to supply the type you require:
SampleHttpResquestAndResponse.AdonisRequestResponseMethod<string>(a, b, c);
I see 2 things wrong here:
The method is both a generic method.
Since it's a generic method, you must provide a type for it:
SampleHttpResquestAndResponse samp = new SampleHttpResquestAndResponse ();
samp.AdonisRequestResponseMethod<SomeType>(a, b, c);
However, that's not the complete answer,
It's a static method, which means that you can't reference the method from an instance of the class, rather you must reference it from the class type
SampleHttpResquestAndResponse.AdonisRequestResponseMethod<SomeType>(a, b, c);
Oh, and one more thing... SampleHttpResquestAndResponse has an extra 's' in the 'Request' portion of the name. That might give you headaches later. Hope this helps!
Related
I am having a bad time trying to consume an XML service.
This is my code to consume the service (it is a public service so you can consume it):
using( var client = new HttpClient() )
{
client.DefaultRequestHeaders
.Accept
.Add( new MediaTypeWithQualityHeaderValue( "text/xml" ) );
var request = new HttpRequestMessage( HttpMethod.Get, "https://gee.bccr.fi.cr/Indicadores/Suscripciones/WS/wsindicadoreseconomicos.asmx/ObtenerIndicadoresEconomicosXML?Indicador=317&FechaInicio=20%2F04%2F2022&FechaFinal=20%2F04%2F2022&Nombre=Jos%C3%A9+Miguel+Torres+G%C3%B3mez&SubNiveles=N&CorreoElectronico=josetorres%40outlook.com&Token=2LOEU2EM8O" );
var returnedXml = client.SendAsync( request ).Result.Content.ReadAsStringAsync().Result;
Console.WriteLine( returnedXml );
}
The response I get from there is the following, adding the console screenshot due to it returns special scape chars:
<string xmlns="http://ws.sdde.bccr.fi.cr">
<Datos_de_INGC011_CAT_INDICADORECONOMIC>
<INGC011_CAT_INDICADORECONOMIC>
<COD_INDICADORINTERNO>317</COD_INDICADORINTERNO>
<DES_FECHA>2022-04-20T00:00:00-06:00</DES_FECHA>
<NUM_VALOR>650.10000000</NUM_VALOR>
</INGC011_CAT_INDICADORECONOMIC>
</Datos_de_INGC011_CAT_INDICADORECONOMIC>
</string>
This is the class I use to try to deserialize:
public class Datos_de_INGC011_CAT_INDICADORECONOMIC
{
public INGC011_CAT_INDICADORECONOMIC INGC011_CAT_INDICADORECONOMIC { get; set; }
}
public class INGC011_CAT_INDICADORECONOMIC
{
public int COD_INDICADORINTERNO { get; set; }
public DateTime DES_FECHA { get; set; }
public double NUM_VALOR { get; set; }
}
But when I try to Deserialize the string I get the error: There is an error in XML document. Data at the root level is invalid. And due to I don't use to work with XML data I am stocked here.
The problem is that the "outer" XML is a wrapper for the "inner" one, which is encoded as text node for the first. In other words, that's NOT a single document, rather two different documents nested.
My guess is about the outer one, which looks like a descriptor for what itself contains.
That being said, you can extract what you need in a two-step job:
using System;
using System.Xml.Linq;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using( var client = new HttpClient() )
{
client.DefaultRequestHeaders
.Accept
.Add( new MediaTypeWithQualityHeaderValue( "text/xml" ) );
var request = new HttpRequestMessage( HttpMethod.Get, " ... " );
var returnedXml = client.SendAsync( request ).Result.Content.ReadAsStringAsync().Result;
Console.WriteLine( returnedXml );
//create a XML DOM from the returned payload
XDocument xdoc_outer = XDocument.Parse(returnedXml );
//extract the inner document as text (being a true-text node)
string inner_text = (string)xdoc_outer.Root;
//deserialize the text straight to a POCO shaped accordingly
var serializer = new XmlSerializer(typeof(Datos_de_INGC011_CAT_INDICADORECONOMIC));
using (var reader = XmlReader.Create(new StringReader(inner_text)))
{
//'result' contains the deserialized POCO, unless something went wrong!
var result = (Datos_de_INGC011_CAT_INDICADORECONOMIC)serializer.Deserialize(reader);
}
}
Probably there are better yet compact ways to achieve the same result, but I think that's pretty clear.
As final note, I reccomend to use async/await than accessing the data through the Result property.
Looks like the problem you are having is because of the outer element you have in your xml (string)
You can use one of the ways mentioned here (https://stackoverflow.com/a/19613934/3377344) in this post to create your class.
I used the paste special method shown there and here is the class I was able to generate:
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.sdde.bccr.fi.cr")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.sdde.bccr.fi.cr", IsNullable = false)]
public partial class #string
{
private stringDatos_de_INGC011_CAT_INDICADORECONOMIC datos_de_INGC011_CAT_INDICADORECONOMICField;
/// <remarks/>
public stringDatos_de_INGC011_CAT_INDICADORECONOMIC Datos_de_INGC011_CAT_INDICADORECONOMIC
{
get
{
return this.datos_de_INGC011_CAT_INDICADORECONOMICField;
}
set
{
this.datos_de_INGC011_CAT_INDICADORECONOMICField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.sdde.bccr.fi.cr")]
public partial class stringDatos_de_INGC011_CAT_INDICADORECONOMIC
{
private stringDatos_de_INGC011_CAT_INDICADORECONOMICINGC011_CAT_INDICADORECONOMIC iNGC011_CAT_INDICADORECONOMICField;
/// <remarks/>
public stringDatos_de_INGC011_CAT_INDICADORECONOMICINGC011_CAT_INDICADORECONOMIC INGC011_CAT_INDICADORECONOMIC
{
get
{
return this.iNGC011_CAT_INDICADORECONOMICField;
}
set
{
this.iNGC011_CAT_INDICADORECONOMICField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.sdde.bccr.fi.cr")]
public partial class stringDatos_de_INGC011_CAT_INDICADORECONOMICINGC011_CAT_INDICADORECONOMIC
{
private ushort cOD_INDICADORINTERNOField;
private System.DateTime dES_FECHAField;
private decimal nUM_VALORField;
/// <remarks/>
public ushort COD_INDICADORINTERNO
{
get
{
return this.cOD_INDICADORINTERNOField;
}
set
{
this.cOD_INDICADORINTERNOField = value;
}
}
/// <remarks/>
public System.DateTime DES_FECHA
{
get
{
return this.dES_FECHAField;
}
set
{
this.dES_FECHAField = value;
}
}
/// <remarks/>
public decimal NUM_VALOR
{
get
{
return this.nUM_VALORField;
}
set
{
this.nUM_VALORField = value;
}
}
}
Once you have that class ready, you should be able to get the deserialize to work.
I used something like this:
class Program
{
static void Main(string[] args)
{
string myxml = $#"
<string xmlns = ""http://ws.sdde.bccr.fi.cr"">
<Datos_de_INGC011_CAT_INDICADORECONOMIC>
<INGC011_CAT_INDICADORECONOMIC>
<COD_INDICADORINTERNO>317</COD_INDICADORINTERNO>
<DES_FECHA>2022-04-20T00:00:00-06:00</DES_FECHA>
<NUM_VALOR>650.10000000</NUM_VALOR>
</INGC011_CAT_INDICADORECONOMIC>
</Datos_de_INGC011_CAT_INDICADORECONOMIC>
</string>
";
var res = XMLToObject(myxml, typeof(#string));
}
public static object XMLToObject(string xml, Type type, string xmlnamespace = "http://ws.sdde.bccr.fi.cr")
{
object result = null;
using (var stream = new StringReader(xml))
{
using(var reader = new XmlTextReader(stream))
{
var xmlRootAttr = new XmlRootAttribute();
xmlRootAttr.Namespace = xmlnamespace;
xmlRootAttr.ElementName = type.Name;
var serializer = new XmlSerializer(type, xmlRootAttr);
result = serializer.Deserialize(reader);
}
}
return result;
}
}
When I DeSerialize an object from file, the fields whit equal references, don't have same references any more.
This is an example:
in this example, I created an object a1 from type A. then I saved it in a file and load it into new object named a2. In a1 there is b1 and b2 which are same (equal references), so when I set a1.b1.x = 5;, the value of a1.b2.x will change to 5 also, but after save/load, when I set a2.b1.x = 5;, the value of a2.b2.x will not change!!!
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;
namespace test
{
public class SerializeObjectTest
{
public static void Test()
{
var a1 = new A();
a1.init();
SerializeObject<A>(a1, "d:\\1.xml");
var a2 = DeSerializeObject<A>("d:\\1.xml");
a1.b1.x = 5; // this will change also the value of a1.b2.x
a2.b1.x = 5; // this will not!!!!! change also the value of a2.b2.x
MessageBox.Show(
"a1.b1.x==a1.b2.x : " + a1.b1.x + "?=" + a1.b2.x + "\r\n" +
"a2.b1.1==a2.b2.x : " + a2.b1.x + "?=" + a2.b2.x + " !!\r\n", "Save.SaveAble"
);
}
public class A
{
public void init()
{
b1 = new B() { x = 100 };
b2 = b1;
}
public B b1;
public B b2;
}
public class B
{
public double x;
}
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
public static void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
stream.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
}
/// <summary>
/// Deserializes an xml file into an object list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public static T DeSerializeObject<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString))
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = new XmlTextReader(read))
{
objectOut = (T)serializer.Deserialize(reader);
reader.Close();
}
read.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
return objectOut;
}
}
}
I developed an project my self that can save/load/clone objects in c# and it keeps references to object, it is available here.
It also can save internal and private fields. There are some attributes to how save fields or types (like donsave, saveas, saveif, ...).
I am trying to deserialize an XML file into an object in the Program file of my Windows Forms application as below:
List<UserAccessGroup> AccessGroups = new List<UserAccessGroup>();
AccessGroups = SerializerHelper.DeSerializeObject<List<UserAccessGroup>>(#"C:\Users\Michael"
+ #"\Google Drive\FDM Dev Course Content\Workspace\SystemAdmin\SystemAdmin\"
+ #"XML Data Store\UserAccessGroups.xml");
UserAccessGroup SystemAdmin_App = new UserAccessGroup();
foreach (UserAccessGroup group in AccessGroups)
{
if (group.Name.Equals("Admin Operators"))
{
SystemAdmin_App = group;
}
}
When I run this code, I am getting an unhandled exception in my foreach loop, stating that Access Groups is null.
However, when I copy and paste this snippet of code into a blank console application, it runs fine and when I check AccessGroups with a break point, it has 4 members, as expected.
Can anyone please tell me why deserialization is not working in my program file?
Also, here is my XML file:
<?xml version="1.0"?>
<ArrayOfUserAccessGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserAccessGroup>
<Name>Admin Operators</Name>
<Access_Group>
<int>999</int>
</Access_Group>
</UserAccessGroup>
<UserAccessGroup>
<Name>Shareholders</Name>
<Access_Group />
</UserAccessGroup>
<UserAccessGroup>
<Name>Brokers</Name>
<Access_Group />
</UserAccessGroup>
<UserAccessGroup>
<Name>StockExMgrs</Name>
<Access_Group />
</UserAccessGroup>
</ArrayOfUserAccessGroup>
EDIT: forgot to include the SerializerHelper class that I am using for serialization/deserialization, please see below:
public static class SerializerHelper
{
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(
"SerializerHelper.cs");
public static void SerializeObject<T>(string filepath, T serializableObject)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(filepath);
stream.Close();
}
}
catch (Exception ex)
{
//Log exception here
logger.Error("Error Serializing: " + ex.Message);
}
}
/// <summary>
/// Deserializes an xml file into an object list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public static T DeSerializeObject<T>(string filepath)
{
T objectOut = default(T);
if (!System.IO.File.Exists(filepath)) return objectOut;
try
{
string attributeXml = string.Empty;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(filepath);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString))
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = new XmlTextReader(read))
{
objectOut = (T)serializer.Deserialize(reader);
reader.Close();
}
read.Close();
}
}
catch (Exception ex)
{
//Log exception here
logger.Error("Error Deserializing: " + ex.Message);
}
return objectOut;
}
}
EDIT: UserAccessGroup class below:
[Serializable]
public class UserAccessGroup : IUserAccessGroup
{
private String name;
private List<int> AccessGroup = new List<int>();
public String Name
{
get { return name; }
set { name = value; }
}
public List<int> Access_Group
{
get { return AccessGroup; }
set { AccessGroup = value; }
}
public UserAccessGroup()
{
}
public UserAccessGroup(String name)
{
this.name = name;
}
public List<int> getUserIDs()
{
return AccessGroup;
}
public void removeUser(int userID)
{
AccessGroup.Remove(userID);
return;
}
public void addUser(int userID)
{
AccessGroup.Add(userID);
return;
}
}
The main problem can be summarized as:
T objectOut = default(T);
if (!System.IO.File.Exists(filepath)) return objectOut;
try
{
// ...
}
catch (Exception ex)
{
//Log exception here
logger.Error("Error Deserializing: " + ex.Message);
}
return objectOut;
(note that default(T) for T=List<UserAccessGroup> is null)
So: for AccessGroups to be null, one of 2 things is happening:
the file does not exist (so the code is exiting near the top)
an exception is being thrown
Check each of these. If the first: add it. If the second: read the .Message, and the .InnerException.Message etc (XmlSerializer is very big on inner-exceptions)
XmlSerializer will not return null for the root object of a list / array, so: it is one of those two things.
Put a breakpoint on the not-exists return, and in the catch, and you should find what is happening. Alternatively, look at where-ever logger writes. Maybe also add something that writes to logger when the file doesn't exist.
This is my code:
Process pr2 = new Process();
pr2.StartInfo.FileName = "show-snps";
pr2.StartInfo.Arguments = #"-Clr -x 2 out.delta > out.snps";
pr2.Start();
pr2.WaitForExit();
show-snps writes an error. when I delete the part "> out.snps" everything is ok and it writes the result into the terminal, but I need to redirect it to the text file.
How can I do this?
You can't redirect like that when you are starting the program like that. It requires a shell such as CMD.EXE to do that.
Instead, you need to set ProcessStartInfo.RedirectStandardOutput to a stream that you manage yourself.
There's an example here.
That example shows how to get the data that the console process creates via a StreamReader. For your requirement, you would read from that StreamReader and write to a FileStream output.
In case it's any help, here's a utility class I wrote years ago (for .Net 2) which might be instructive:
using System;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Collections;
using System.Collections.Specialized;
namespace ProcessUtilities
{
/// <summary>
/// Encapsulates an executable program.
/// This class makes it easy to run a console app and have that app's output appear
/// in the parent console's window, and to redirect input and output from/to files.
/// </summary>
/// <remarks>
/// To use this class:
/// (1) Create an instance.
/// (2) Set the ProgramFileName property if a filename wasn't specified in the constructor.
/// (3) Set other properties if required.
/// (4) Call Run().
/// </remarks>
public class Executable
{
#region Constructor
/// <summary>Runs the specified program file name.</summary>
/// <param name="programFileName">Name of the program file to run.</param>
public Executable(string programFileName)
{
ProgramFileName = programFileName;
_processStartInfo.ErrorDialog = false;
_processStartInfo.CreateNoWindow = false;
_processStartInfo.UseShellExecute = false;
_processStartInfo.RedirectStandardOutput = false;
_processStartInfo.RedirectStandardError = false;
_processStartInfo.RedirectStandardInput = false;
_processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
_processStartInfo.Arguments = "";
}
/// <summary>Constructor.</summary>
public Executable(): this(string.Empty)
{
}
#endregion // Constructor
#region Public Properties
/// <summary>The filename (full pathname) of the executable.</summary>
public string ProgramFileName
{
get
{
return _processStartInfo.FileName;
}
set
{
_processStartInfo.FileName = value;
}
}
/// <summary>The command-line arguments passed to the executable when run. </summary>
public string Arguments
{
get
{
return _processStartInfo.Arguments;
}
set
{
_processStartInfo.Arguments = value;
}
}
/// <summary>The working directory set for the executable when run.</summary>
public string WorkingDirectory
{
get
{
return _processStartInfo.WorkingDirectory;
}
set
{
_processStartInfo.WorkingDirectory = value;
}
}
/// <summary>
/// The file to be used if standard input is redirected,
/// or null or string.Empty to not redirect standard input.
/// </summary>
public string StandardInputFileName
{
set
{
_standardInputFileName = value;
_processStartInfo.RedirectStandardInput = !string.IsNullOrEmpty(value);
}
get
{
return _standardInputFileName;
}
}
/// <summary>
/// The file to be used if standard output is redirected,
/// or null or string.Empty to not redirect standard output.
/// </summary>
public string StandardOutputFileName
{
set
{
_standardOutputFileName = value;
_processStartInfo.RedirectStandardOutput = !string.IsNullOrEmpty(value);
}
get
{
return _standardOutputFileName;
}
}
/// <summary>
/// The file to be used if standard error is redirected,
/// or null or string.Empty to not redirect standard error.
/// </summary>
public string StandardErrorFileName
{
set
{
_standardErrorFileName = value;
_processStartInfo.RedirectStandardError = !string.IsNullOrEmpty(value);
}
get
{
return _standardErrorFileName;
}
}
#endregion // Public Properties
#region Public Methods
/// <summary>Add a set of name-value pairs into the set of environment variables available to the executable.</summary>
/// <param name="variables">The name-value pairs to add.</param>
public void AddEnvironmentVariables(StringDictionary variables)
{
if (variables == null)
throw new ArgumentNullException("variables");
StringDictionary environmentVariables = _processStartInfo.EnvironmentVariables;
foreach (DictionaryEntry e in variables)
environmentVariables[(string)e.Key] = (string)e.Value;
}
/// <summary>Run the executable and wait until the it has terminated.</summary>
/// <returns>The exit code returned from the executable.</returns>
public int Run()
{
Thread standardInputThread = null;
Thread standardOutputThread = null;
Thread standardErrorThread = null;
_standardInput = null;
_standardError = null;
_standardOutput = null;
int exitCode = -1;
try
{
using (Process process = new Process())
{
process.StartInfo = _processStartInfo;
process.Start();
if (process.StartInfo.RedirectStandardInput)
{
_standardInput = process.StandardInput;
standardInputThread = startThread(new ThreadStart(supplyStandardInput), "StandardInput");
}
if (process.StartInfo.RedirectStandardError)
{
_standardError = process.StandardError;
standardErrorThread = startThread(new ThreadStart(writeStandardError), "StandardError");
}
if (process.StartInfo.RedirectStandardOutput)
{
_standardOutput = process.StandardOutput;
standardOutputThread = startThread(new ThreadStart(writeStandardOutput), "StandardOutput");
}
process.WaitForExit();
exitCode = process.ExitCode;
}
}
finally // Ensure that the threads do not persist beyond the process being run
{
if (standardInputThread != null)
standardInputThread.Join();
if (standardOutputThread != null)
standardOutputThread.Join();
if (standardErrorThread != null)
standardErrorThread.Join();
}
return exitCode;
}
#endregion // Public Methods
#region Private Methods
/// <summary>Start a thread.</summary>
/// <param name="startInfo">start information for this thread</param>
/// <param name="name">name of the thread</param>
/// <returns>thread object</returns>
private static Thread startThread(ThreadStart startInfo, string name)
{
Thread t = new Thread(startInfo);
t.IsBackground = true ;
t.Name = name;
t.Start();
return t;
}
/// <summary>Thread which supplies standard input from the appropriate file to the running executable.</summary>
private void supplyStandardInput()
{
// feed text from the file a line at a time into the standard input stream
using (StreamReader reader = File.OpenText(_standardInputFileName))
using (StreamWriter writer = _standardInput)
{
writer.AutoFlush = true;
for (;;)
{
string textLine = reader.ReadLine();
if (textLine == null)
break;
writer.WriteLine(textLine);
}
}
}
/// <summary>Thread which outputs standard output from the running executable to the appropriate file.</summary>
private void writeStandardOutput()
{
using (StreamWriter writer = File.CreateText(_standardOutputFileName))
using (StreamReader reader = _standardOutput)
{
writer.AutoFlush = true;
for (;;)
{
string textLine = reader.ReadLine();
if (textLine == null)
break;
writer.WriteLine(textLine);
}
}
if (File.Exists(_standardOutputFileName))
{
FileInfo info = new FileInfo(_standardOutputFileName);
// if the error info is empty or just contains eof etc.
if (info.Length < 4)
info.Delete();
}
}
/// <summary>Thread which outputs standard error output from the running executable to the appropriate file.</summary>
private void writeStandardError()
{
using (StreamWriter writer = File.CreateText(_standardErrorFileName))
using (StreamReader reader = _standardError)
{
writer.AutoFlush = true;
for (;;)
{
string textLine = reader.ReadLine();
if (textLine == null)
break;
writer.WriteLine(textLine);
}
}
if (File.Exists(_standardErrorFileName))
{
FileInfo info = new FileInfo(_standardErrorFileName);
// if the error info is empty or just contains eof etc.
if (info.Length < 4)
info.Delete();
}
}
#endregion // Private Methods
#region Private Fields
private StreamReader _standardError ;
private StreamReader _standardOutput ;
private StreamWriter _standardInput ;
private string _standardInputFileName;
private string _standardOutputFileName;
private string _standardErrorFileName;
ProcessStartInfo _processStartInfo = new ProcessStartInfo();
#endregion // Private Fields
}
}
This is an old question, but it came up on the first google link for searching for how to redirect the standard output of a launched Process to a file.
The answer I think works well is to add a OutputDataReceived event and write to the file there.
Here is a complete working example.
using System;
using System.IO;
using System.Diagnostics;
using System.Text;
class StandardAsyncOutputExample
{
public static void Main()
{
var outputStream = new StreamWriter("output.txt");
Process process = new Process();
process.StartInfo.FileName = "ipconfig.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
outputStream.WriteLine(e.Data);
}
});
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
process.Close();
outputStream.Close();
Console.WriteLine("\n\nPress any key to exit.");
Console.ReadLine();
}
}
It didn't work because > redirect was supported by cmd.exe shell. Try the following code instead.
Process pr2 = new Process();
pr2.StartInfo.FileName = #"c:\windows\system32\cmd.exe";
pr2.StartInfo.Arguments = #"/k \"show-snps -Clr -x 2 out.delta > out.snps\"";
pr2.Start();
pr2.WaitForExit();
string jsondata = #"{""meta"":{""code"":200}}";
dynamic json = JsonConvert.DeserializeObject(jsondata);
I have above json data and I created class for it. I have also deserialized it - how can I iterate this json variable
public class Meta
{
public int code { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
}
To Work with your code, you should user the typed convert
string jsondata = #"{""meta"":{""code"":200}}";
Meta json = JsonConvert.DeserializeObject<Meta>(jsondata);
Then you can Acces all the members in the meta obj.
With normal .net json runtime you can deserialize a string
string jsondata = #"{""meta"":{""code"":200}}"
Meta meta = JsonHelper.JsonDeserialize<Meta>(jsondata);
For more info see http://www.codeproject.com/Articles/272335/JSON-Serialization-and-Deserialization-in-ASP-NET
You need to have this code ofc
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
/// <summary>
/// JSON Serialization and Deserialization Assistant Class
/// </summary>
public class JsonHelper
{
/// <summary>
/// JSON Serialization
/// </summary>
public static string JsonSerializer<T> (T t)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, t);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return jsonString;
}
/// <summary>
/// JSON Deserialization
/// </summary>
public static T JsonDeserialize<T> (string jsonString)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
}