I have a requirement of executing a C# class in the string format and populate an object with the properties of that class. To achieve the requirement I was doing a POC and that's failed.
Following code is failing to evaluate where i was trying to update the input model.
Program.cs
using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;
namespace CSCodeExecuter
{
class Program
{
static void Main(string[] args)
{
Model input = new Model();
string scriptId = "123";
ScriptManager sriptMgr = new ScriptManager();
sriptMgr.ExecuteScript<Model>(scriptId, ref input);
Console.WriteLine(input.ToString());
Console.ReadKey();
}
}
}
ScriptManager.cs
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSCodeExecuter
{
public class ScriptManager
{
public void ExecuteScript<T>(string scriptId, ref T input)
{
try
{
string inputSript = GetStriptById(scriptId);
var scriptOptions = ScriptOptions.Default;
scriptOptions.AddReferences("CSCodeExecuter");
Execute(inputSript, scriptOptions);
var result = Execute("new ScriptedClass().input", scriptOptions);
}
catch (Exception ex)
{
throw;
}
}
private string GetStriptById(string id)
{
string csSript = #" public class ScriptedClass
{
public CSCodeExecuter.Model input {get;set;}
public void ScriptedClass()
{
{" + GetInternalScript() + #"}
}
}";
return csSript;
}
private string GetInternalScript()
{
return "input.Id = \"1111\"; " + "input.Name = \"test\"; " + "input.Phone = \"1234567890\"; ";
}
private static ScriptState<object> scriptState = null;
public static object Execute(string code, dynamic scriptOptions)
{
scriptState = scriptState == null ? CSharpScript.RunAsync(code).Result : scriptState.ContinueWithAsync(code).Result;
if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
return scriptState.ReturnValue;
return null;
}
}
}
Model.CS
namespace CSCodeExecuter
{
public class Model
{
public string Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
}
Now it works:
using System;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace CSCodeExecuter
{
public class ScriptManager
{
public void ExecuteScript<T>(string scriptId, ref T input)
{
try
{
string inputSript = GetStriptById(scriptId);
var scriptOptions = ScriptOptions.Default.AddReferences("CSCodeExecuter");
var result = Execute(inputSript, scriptOptions);
}
catch (Exception ex)
{
throw;
}
}
private string GetStriptById(string id)
{
string csSript =
#"
public class ScriptedClass
{
public CSCodeExecuter.Model input {get;set;}
public ScriptedClass()
{
" + GetInternalScript() + #"
}
}
return (new ScriptedClass()).input;";
return csSript;
}
private string GetInternalScript()
{
return "input = new CSCodeExecuter.Model(); input.Id = \"1111\"; input.Name = \"test\"; input.Phone = \"1234567890\"; ";
}
private static ScriptState<object> scriptState = null;
public static object Execute(string code, dynamic scriptOptions)
{
scriptState = scriptState == null ? CSharpScript.RunAsync(code, scriptOptions).Result : scriptState.ContinueWithAsync(code).Result;
if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
return scriptState.ReturnValue;
return null;
}
}
}
You had several errors:
not use options(second parameter) in Execute
extra parentheses in ctor
ctor should not has a result type(void)
input property was not initialized
scripts with creating of class and using of it was separated
Related
Currently it is returning a single unintelligible chunk composed of multiple of these things glued one next to the other like this:
at ProyectX.Services.Service.Validate(IList 1 myParam) in
C:\\Repositories\\projectx\\src\\ProyectX.Services\\Service.cs:line
116\r\n at ProyectX.Services.Service.Validate(IList 1 myParam) in
C:\\Repositories\\projectx\\src\\ProyectX.Services\\Service.cs:line
116\r\n
Goal:
at ProyectX.Services.Service.Validate(IList 1 myParam) in C:\Repositories\projectx\src\ProyectX.Services\Service.cs:line 116
at ProyectX.Services.Service.Validate(IList 1 myParam) in C:\Repositories\projectx\src\ProyectX.Services\Service.cs:line 116
I tried with
Regex.Unescape(exception.StackTrace)
JsonSerializer.Serialize(exception.StackTrace, new JsonSerializerOptions() {WriteIndented = true });
The middleware is in Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<ErrorHandlerMiddleware>();
Middleweare:
using System;
using System.Collections.Generic;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using ProyectX.Domain.Exceptions;
using ProyectX.Domain.Models;
namespace ProyectX.API.Middleware
{
public class ErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, IWebHostEnvironment env)
{
try
{
await _next(context);
}
catch (Exception exception)
{
var response = context.Response;
response.ContentType = "application/json";
switch (exception)
{
case InvalidOperationException:
response.StatusCode = (int)HttpStatusCode.BadRequest;
break;
default:
response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
var details = new Dictionary<string, string>
{
{ "Message", exception.Message },
};
if (env.IsDevelopment())
{
details.Add("StackTrace", exception.StackTrace);
}
var errorResponse = new ErrorResponseModel(exception, details);
var result = JsonSerializer.Serialize(errorResponse);
await response.WriteAsync(result);
}
}
}
}
ErrorResponseModel
using System;
using System.Collections.Generic;
namespace ProyectX.Domain.Models
{
public class ErrorResponseModel
{
public ErrorResponseModel(Exception ex, Dictionary<string, string> details)
{
Type = ex.GetType().Name;
Details = details;
}
public string Type { get; set; }
public IDictionary<string, string> Details { get; set; }
}
}
I would suggest changing a bit in your ErrorResponseModel class so that your dictionary accept object type as value, like Dictionary<string, object>. Here comes the idea, that you can both added string OR string array.
So for your tacktrace, you can split it multiple line using split by "\r\n" and get a string array of it, that I can pass to my StackTrace value.
So lets come to your model:
public class ErrorResponseModel
{
public ErrorResponseModel(Exception ex, Dictionary<string, object> details)
{
Type = ex.GetType().Name;
Details = details;
}
public string Type { get; set; }
public IDictionary<string, object> Details { get; set; }
}
Here is the part that handle exception:
var details = new Dictionary<string, object>
{
{ "Message", exception.Message} ,
};
var lines = exception.StackTrace?.Split("\r\n").Select(e => e.TrimStart());
details.Add("StackTrace", lines);
var errorResponse = new ErrorResponseModel(exception, details);
var result = JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions() { WriteIndented = true });
All this return following out:
Exception information model using StackTrace and StackFrame classes
There's a StackTrace class which can help you to get list of StackFrame objects. Each frame, includes information like:
Line Number
Method (Class, Assembly)
Code File
Looking into ASP.NET Core ErrorPage and DeveloperExceptionPageMiddleware you will see the framework has created a model class including the exception information like stack frame and then in the error page has formatted the model and showed in a readable format.
This is how Exception class also generates the StackTrace: by calling StackTrace.ToString which gets the stack frames and format above information in a string.
You can also do the same and generate the string in a better format, or as a better idea, create an exception or stacktrace model and let the formatting be done later.
For example, this is the exception model (including stacktrace) that you can have:
{
"Message":"Attempted to divide by zero.",
"StackFrames":[
{
"LineNumber":13,
"Method":"Main(String[] args)",
"Class":"SampleConsoleApp.Program",
"AssemblyName":"SampleConsoleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"AssemblyFile":"file:///C:/SampleConsoleApp/bin/Debug/netcoreapp3.1/SampleConsoleApp.dll",
"CodeFile":"C:\\SampleConsoleApp\\Program.cs"
},
{
"LineNumber":23,
"Method":"Divide(Int32 x, Int32 y)",
"Class":"SampleConsoleApp.Program",
"AssemblyName":"SampleConsoleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"AssemblyFile":"file:///C:/SampleConsoleApp/bin/Debug/netcoreapp3.1/SampleConsoleApp.dll",
"CodeFile":"C:\\SampleConsoleApp\\Program.cs"
}
],
"InnerException":null
}
Above json string is created from my exception model:
try
{
}
catch (Exception ex)
{
var model = ExceptionModel.Create(ex);
// You can convert it to json and store it
// Or format it and write to log
}
ExceptionModel including StackTrace
Here is how I've implemented exception model:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
public class ExceptionModel
{
public string Message { get; set; }
public IEnumerable<StackFrameModel> StackFrames { get; set; }
public ExceptionModel InnerException { get; set; }
public static ExceptionModel Create(Exception ex = null)
{
var trace = ex == null ? new StackTrace(true) : new StackTrace(ex, true);
var model = new ExceptionModel();
model.Message = ex?.Message;
model.StackFrames = trace.GetFrames().Reverse()
.Select(x => new StackFrameModel()
{
LineNumber = x.GetFileLineNumber(),
Method = GetMethodSignature(x.GetMethod()),
Class = x.GetMethod()?.DeclaringType?.FullName,
AssemblyName = x.GetMethod()?.DeclaringType?.Assembly?.FullName,
AssemblyFile = x.GetMethod()?.DeclaringType?.Assembly?.CodeBase,
CodeFile = x.GetFileName(),
});
if (ex?.InnerException != null)
model.InnerException = ExceptionModel.Create(ex.InnerException);
return model;
}
private static string GetTypeName(Type type)
{
return type?.FullName?.Replace('+', '.');
}
private static string GetMethodSignature(MethodBase mb)
{
var sb = new StringBuilder();
sb.Append(mb.Name);
// deal with the generic portion of the method
if (mb is MethodInfo && ((MethodInfo)mb).IsGenericMethod)
{
Type[] typars = ((MethodInfo)mb).GetGenericArguments();
sb.Append("[");
int k = 0;
bool fFirstTyParam = true;
while (k < typars.Length)
{
if (fFirstTyParam == false)
sb.Append(",");
else
fFirstTyParam = false;
sb.Append(typars[k].Name);
k++;
}
sb.Append("]");
}
// arguments printing
sb.Append("(");
ParameterInfo[] pi = mb.GetParameters();
bool fFirstParam = true;
for (int j = 0; j < pi.Length; j++)
{
if (fFirstParam == false)
sb.Append(", ");
else
fFirstParam = false;
String typeName = "<UnknownType>";
if (pi[j].ParameterType != null)
typeName = pi[j].ParameterType.Name;
sb.Append(typeName + " " + pi[j].Name);
}
sb.Append(")");
return sb.ToString();
}
}
public class StackFrameModel
{
public int LineNumber { get; set; }
public string Method { get; set; }
public string Class { get; set; }
public string AssemblyName { get; set; }
public string AssemblyFile { get; set; }
public string CodeFile { get; set; }
}
I'm doing some WPF project where I want to make a method, which deletes element from ObservableCollection when I click on it. But for some reason is not doing right. I check with debugger and when it comes to the statement where I call method for the removing element, it shows that my object (on which I call all methods) is empty or. null.
I know it's dumb question and for sure very dumb mistake, which I overlooked but I can't find the solution how to fix it.
Code:
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace facebook {
/// <summary>
/// Interaction logic for prikazObjave.xaml
/// </summary>
public partial class prikazObjave : UserControl {
Oseba oseba = new Oseba();
public prikazObjave() {
InitializeComponent();
}
public prikazObjave(Oseba os) {
InitializeComponent();
oseba = os;
}
private void item_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
var TextBlockName = ((TextBlock)sender).Name;
string newValue = Interaction.InputBox("Vnesi novo vrednost", "New value", "", 0, 0);
if (newValue != "" && newValue != null) {
((TextBlock)sender).Text = newValue;
}
}
private void delete_post_event(object sender, MouseButtonEventArgs e) {
var temp = (StackPanel)sender;
Objava objava = (Objava)(temp.DataContext);
if(oseba.posts.Count > 1) { //<---here, oseba is null
try {
oseba.izbrisiObjavo(oseba, objava);
MessageBox.Show("Objava uspešno izbrisana");
}
catch (Exception ex) {
Console.WriteLine("Napaka pri brisanju objave\n\n" + ex.Message + "\n" + ex.StackTrace);
}
}
else {
Console.WriteLine("Seznam objav je prazen");
return;
}
}
private void dodajKomentarBtn_Click(object sender, RoutedEventArgs e) {
string vsebina = Interaction.InputBox("Vnesi komentar", "Komentiraj", "", 0, 0);
if (vsebina != "" && vsebina != null) {
oseba.dodajKomentar(vsebina);
}
}
}
}
And this is the class method for removing the element from the Collection:
public void izbrisiObjavo(Oseba oseba, Objava objava) {
if(objava != null) {
//posts.Remove(objava);
try {
//posts.Remove(posts.Where(i => i.Vsebina == objava.Vsebina).Single());
Objava temp = objava;
oseba.posts.Remove(temp);
}
catch(Exception e) {
Console.WriteLine("Napaka pri brisanju objave (Oseba)\n\n" + e.Message + "\n" + e.StackTrace);
}
}
else {
Console.WriteLine("objava je null\n");
return;
}
}
Oseba class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.IO;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Windows.Forms;
namespace facebook {
[Serializable()]
public class Oseba : INotifyPropertyChanged {
private string ime;
private string priimek;
private int starost;
private string spol;
private string oMeni;
private string zaposlitev;
private string profilnaSlika;
private string naslovnaSlika;
ObservableCollection<String> solanje = new ObservableCollection<string>(); //vse vrste šolanja
ObservableCollection<Prijatelj> friends = new ObservableCollection<Prijatelj>(); //seznam prijateljev
ObservableCollection<Objava> posts = new ObservableCollection<Objava>(); //seznam objav
ObservableCollection<String> pocutje = new ObservableCollection<string>();
public Oseba() { }
public Oseba(string ime, string priimek, int starost, string spol, string oMeni, string zaposlitev) {
this.ime = ime;
this.priimek = priimek;
this.starost = starost;
this.spol = spol;
this.oMeni = oMeni;
this.zaposlitev = zaposlitev;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName) {
if(PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public void dodajPrijatelja(Prijatelj prijatelj) {
friends.Add(prijatelj);
}
public void dodajSolo(string sola) {
solanje.Add(sola);
}
public void dodajObjavo(string vsebina, string zasebnost, ObservableCollection<String> prijatelji, string datoteka, string kraj, string pocutje) {
posts.Add(new Objava(vsebina, zasebnost, prijatelji, datoteka, kraj, pocutje));
}
public void dodajPocutje(string path) {
pocutje.Add(path);
}
public void dodajKomentar(string vsebina) {
if(vsebina != null) {
try {
//posts[0].ko
}
catch (Exception e) {
MessageBox.Show("Napaka pri dodajanju komentarja!\n\n" + e.Message + "\n" + e.StackTrace);
}
}
else {
MessageBox.Show("Vnesite komentar!");
return;
}
}
public void izbrisiObjavo(Oseba oseba, Objava objava) {
if(objava != null) {
//posts.Remove(objava);
try {
//posts.Remove(posts.Where(i => i.Vsebina == objava.Vsebina).Single());
Objava temp = objava;
oseba.posts.Remove(temp);
}
catch(Exception e) {
Console.WriteLine("Napaka pri brisanju objave (Oseba)\n\n" + e.Message + "\n" + e.StackTrace);
}
}
else {
Console.WriteLine("objava je null\n");
return;
}
}
public void serialize(Oseba os) {
string dataFile = (#"C:\Users\Admin\Desktop\uv\data.xml");
profilnaSlika = #"E:\Šola\2. letnik\Zimski semester\Uporabniski vmesniki\facebook\images\tony_stark_profile_pic.jpg";
naslovnaSlika = #"E:\Šola\2. letnik\Zimski semester\Uporabniski vmesniki\facebook\images\tony_stark_timeline_pic.jpg";
try {
XmlSerializer mySerializer = new XmlSerializer(typeof(Oseba));
StreamWriter myWritter = new StreamWriter(dataFile);
mySerializer.Serialize(myWritter, os);
myWritter.Close();
}
catch(Exception ex) {
Console.WriteLine("Napaka pri serializaciji(metoda Serialize - razred Oseba)\n\n" + ex.Message + "\n" + ex.StackTrace);
}
}
public Oseba deserialize(string path = #"C:\Users\Admin\Desktop\uv\data.xml") {
Oseba os = new Oseba();
string dataFile = path;
try {
using (var sr = new StreamReader(dataFile)) {
var deserializer = new XmlSerializer(typeof(Oseba));
os = (Oseba)deserializer.Deserialize(sr);
}
}
catch (Exception ex) {
Console.WriteLine("Napaka pri deserializaciji\n\n" + ex.Message + "\n" + ex.StackTrace);
}
return os;
}
public void shrani() {
string dataFile = (#"C:\Users\Admin\Desktop\data.xml");
profilnaSlika = #"E:\Šola\2. letnik\Zimski semester\Uporabniski vmesniki\facebook\images\tony_stark_profile_pic.jpg";
naslovnaSlika = #"E:\Šola\2. letnik\Zimski semester\Uporabniski vmesniki\facebook\images\tony_stark_timeline_pic.jpg";
using (var stream = new FileStream(dataFile, FileMode.Create)) {
var XML = new XmlSerializer(typeof(Oseba));
XML.Serialize(stream, this);
}
}
public Oseba nalozi() {
Oseba os = new Oseba();
string dataFile = (#"C:\Users\Admin\Desktop\data.xml");
try {
using (var sr = new StreamReader(dataFile)) {
var deserializer = new XmlSerializer(typeof(Oseba));
os = (Oseba)deserializer.Deserialize(sr);
}
}
catch (Exception ex) {
var msg = ex.Message;
}
return os;
}
public void odstraniPrijatelja(int index) {
friends.RemoveAt(index);
}
/*
public void sortAsc() {
ObservableCollection<string> prijatelji = new ObservableCollection<string>(friends.OrderBy(i => i));
friends = prijatelji;
}
public void sortDecs() {
ObservableCollection<string> prijatelji = new ObservableCollection<string>(friends.OrderByDescending(i => i));
friends = prijatelji;
}
*/
public string Ime {
get { return ime; }
set {
ime = value;
OnPropertyChanged("Ime");
}
}
public string Priimek {
get { return priimek; }
set {
priimek = value;
OnPropertyChanged("Priimek");
}
}
public int Starost {
get { return starost; }
set {
starost = value;
OnPropertyChanged("Starost");
}
}
public string Spol {
get { return spol; }
set {
spol = value;
OnPropertyChanged("Spol");
}
}
public string OMeni {
get { return oMeni; }
set {
oMeni = value;
OnPropertyChanged("OMeni");
}
}
public string Zaposlitev {
get { return zaposlitev; }
set {
zaposlitev = value;
OnPropertyChanged("Zaposlitev");
}
}
public string ProfilnaSlika {
get { return profilnaSlika; }
set {
profilnaSlika = value;
OnPropertyChanged("ProfilnaSlika");
}
}
public string NaslovnaSlika {
get { return naslovnaSlika; }
set {
naslovnaSlika = value;
OnPropertyChanged("NaslovnaSlika");
}
}
public ObservableCollection<Prijatelj> Friends {
get { return friends; }
set { friends = value;
OnPropertyChanged("Friends");
}
}
public ObservableCollection<String> Solanje {
get { return solanje; }
set {
solanje = value;
OnPropertyChanged("Solanje");
}
}
public ObservableCollection<Objava> Posts {
get { return posts; }
set {
posts = value;
OnPropertyChanged("Posts");
}
}
[XmlIgnore]
public ObservableCollection<String> Pocutje {
get { return pocutje; }
set {
pocutje = value;
OnPropertyChanged("Pocutje");
}
}
}
}
I feel like the silly thing that could possibly lead to this is creating a new prikazObjave (which should be Capitalized class name) as:
var po = new prikazObjave(null);
This would lead to the internal oseba to be null, unless you're explicitly setting po.oseba = null; somewhere.
I debugged my program in chunks and I found that every global variable in userControl named PrikazObjave is null after constructor call is finish.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have a relatively simple console app (framework) which has a tightly coupled classes with properties and my main triggers an async task. These are my property classes:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http; //for HTTP client
using System.Reflection;
using System.Threading.Tasks; //for Async Request/Response
using Newtonsoft.Json; //for JSON properties
namespace PSD2
{
[Serializable]
public class PS
{
public System.Uri BaseURL { get; set; } = new System.Uri("http://192.999.999.999:8888/some/url/here/");
public ConsHeaders Headers { get; set; }
public ConsBody Body { get; set; }
public consAttributes Attributes { get; set; }
}
[Serializable]
public partial class ConsHeaders
{
[JsonProperty("Core-ID")]
public string corID { get; set; }
[JsonProperty("PS-Token")]
public string PS_Token { get; set; }
[JsonProperty("Req-ID")]
public string reqID { get; set; }
}
[Serializable]
public partial class consAttributes
{
[JsonProperty("consId")]
public string consId { get; set; } = String.Empty;
[JsonProperty("consStatus")]
public string consStatus { get; set; } = String.Empty;
[JsonProperty("userName")]
public string userName { get; set; } = String.Empty;
};
[Serializable]
public partial class consBody
{
[JsonProperty("access")]
public AccessHeaders access { get; internal set; }
[JsonProperty("combinedServiceIndicator")]
public Boolean CombinedServiceIndicator { get; set; } = false;
[JsonProperty("frequencyPerDay")]
public int FrequencyPerDay { get; set; } = 4;
[JsonProperty("recurringIndicator")]
public Boolean RecurringIndicator { get; set; } = false;
[JsonProperty("validUntil")]
public string ValidUntil { get; set; } = "9999-12-31";
}
...
Now, my Program class creates an object and in Main I call a class called testing who has my logic behind, nothing more than populating the object properties with values, and calls a Task asycn which is also present inside. Code continues from above as:
public class Program
{
public static PS cnsnt = new PS();
public static void Main(string[] args)
{
Testing test = new Testing();
test.createCONS();
}
public class Testing
{
public void createCONS()
{
try
{
cnsnt.Headers = new ConsHeaders
{
corID = "Something",
reqID = "AnotherThing",
PS_Token = "myTokenValue"
};
cnsnt.Body = new ConsBody
{
access = new AccessHeaders
{
AllPsd2 = "allAccounts",
AvailableAccounts = "YES"
},
CombinedServiceIndicator = false,
FrequencyPerDay = 10,
ValidUntil = "2020-12-31"
};
cnsnt.Attributes = new consAttributes
{
consId = "",
_links_self_href = "",
consStatus = "",
status_href = "",
userName = ""
};
}
catch (System.Exception e)
{
throw new System.Exception("Error - Aborting..");
}
myConsAsync(cnsnt.BaseURL, cnsnt, HttpMethod.Post).GetAwaiter().GetResult();
}
public async static Task myConsAsync(Uri HTTPaddress, PS ConSent, HttpMethod httpMethod)
{
try
{
HttpClient client = new HttpClient();
System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
using (HttpRequestMessage request = new HttpRequestMessage(httpMethod, HTTPaddress))
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//...
client.DefaultRequestHeaders.Add("Core-ID", ConSent.Headers.corID);
client.DefaultRequestHeaders.Add("Req-ID", ConSent.Headers.reqID);
client.DefaultRequestHeaders.Add("PS-Token", ConSent.Headers.PS_Token);
//...
request.Content = new StringContent(JsonConvert.SerializeObject(ConSent, Formatting.Indented), utf8, "application/json");
using (HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
Int32 code = (Int32)response.StatusCode;
string responseBody = response.Content.ReadAsStringAsync().Result.ToString();
try
{
if (responseBody.Contains("consId"))
{
try
{
string responseValues = JSONtoKeyValue(responseBody);
var dict = responseValues.Split('|')
.Select(x => x.Split('='))
.Where(x => x.Length > 1
&& !String.IsNullOrEmpty(x[0].Trim())
&& !String.IsNullOrEmpty(x[1].Trim()))
.ToDictionary(x => x[0].Trim(), x => x[1].Trim());
foreach (KeyValuePair<string, string> entry in dict)
{
if (entry.Value == null)
{
dict.Remove(entry.Key);
}
else
{
string key = entry.Key;
string value = entry.Value;
try
{
if (cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
{
// ---> ERROR: Object reference not set to an instance of an object.
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
}
}
catch (System.Exception e)
{
Console.WriteLine("Failed during processing Property: " + e.Message);
}
}
}
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine(e.StackTrace + "\r\n" + e.Message);
}
}
else
{
throw new System.Exception("Fatal error reading response body for the consent Id. Aborting..");
};
}
catch (System.Exception e)
{
Environment.Exit(13);
}
}
}
}
catch (Exception e)
{
//whatever, Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message + "\r\n" + e.Data);
}
//return
}
// this works as intended.. included just for completion
public static string JSONtoKeyValue(string pString)
{
pString.Trim();
if (pString == null)
{
return "";
}
else
{
pString = pString.Replace("\r\n", "|").Replace(":", "=").Replace("\"", "").Replace("{", "").Replace("}", "").Replace(",", "");
int j = 0, inputlen = pString.Length;
char[] newarr = new char[inputlen];
for (int i = 0; i < inputlen; ++i)
{
char tmp = pString[i];
if (!char.IsWhiteSpace(tmp))
{
newarr[j] = tmp; ++j;
}
}
return new String(newarr, 0, j).Replace("||", "|").Replace("||", "|").Replace("=|", "_").Trim('|');
}
}
}
}
}
Notice in the Task that I want to read a string separated with pipes (a small method does the work nicely) and I try to see if I have this property in my object, and if yes, to populate the value.
However, in line
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
I get the error "Object reference not set to an instance of an object."
I struggle on this one, could someone help me?
You have made a simple mistake.
You check for
(cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
But then you assign with
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value)
Just replace it with,
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value).
Note its cnsnt. Not ConSent.
and you'll be fine. Happy reflecting!
edit:
saw your edit, same thing.
cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key)
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key)
you are basically checking on a different bject if it has a property and then you try to set it on another.
Suggestion.
Why not go:
var keyProperty = cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key);
if(keyProperty != null)
{
keyProperty.SetValue(cnsnt, entry.Value);
}
this way it will not fail, ever.
I am struggling with the this for a few hours now. I only want to use a get in my property. When I call a function, it gets a number from that property(10) and should substract 1 from the 10, which makes 9. But I have no idea how to save this 9, and do it minus 1 everytime, so the next time I call it, it becomes 8. I Hope this is clear enough.
main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
do
{
Zwakmonster zwakmonster = new Zwakmonster();
Sterkmonster sterkmonster = new Sterkmonster();
List<IMonster> monster = new List<IMonster>();
string lijn;
string test = "exit";
string nieuwelijn;
string zwak = "zwakmonster";
string sterk = "sterkmonster";
string groen = "groen";
string geel = "geel";
Sterkmonster henk = new Sterkmonster();
henk.Naam = sterk;
henk.Kleur = groen;
Zwakmonster piet = new Zwakmonster();
piet.Kleur = geel;
piet.Naam = zwak;
Console.WriteLine("Schrijf zwakmonster_iemand of sterkmonster_iemand");
lijn = Console.ReadLine();
if (lijn == test)
{
Environment.Exit(0);
}
else if (lijn.StartsWith("hit"))
{
if (lijn.StartsWith("hit "))
{
nieuwelijn = lijn.Remove(0, 4);
if (nieuwelijn == sterk)
{
henk.Hit();
Console.WriteLine(sterkmonster);
}
else if (nieuwelijn == zwak)
{
piet.Hit();
Console.WriteLine(zwakmonster);
}
else
{
Console.WriteLine("iets ging er fout");
}
}
else
{
Console.WriteLine("Ben je misschien een spatie vergeten na ''hit''?\n");
}
}
else
{
Console.WriteLine("Verkeerd commando ingevoerd\n");
}
} while (1 == 1);
}
}
}
IMonster.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
interface IMonster
{
string Naam
{
get;
set;
}
string Kleur
{
get;
set;
}
int Levens
{
get;
}
void Hit();
}
}
zwakmonster.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Zwakmonster : IMonster
{
private string mijnNaam;
private string mijnKleur;
private int mijnLevens = 10;
private int nieuwelevens;
public string Naam
{
get { return mijnNaam; }
set { mijnNaam = value; }
}
public string Kleur
{
get { return mijnKleur; }
set { mijnKleur = value; }
}
public int Levens
{
get { return mijnLevens; }
}
public void Hit()
{
mijnLevens = mijnLevens - 1;
nieuwelevens = mijnLevens;
Console.WriteLine(nieuwelevens);
}
}
}
Change this
public void Hit()
{
newlife = mijnLevens - 1;
}
to this
public void Hit()
{
mijnLevens = mijnLevens - 1;
newlife = mijnLevens;
}
this will make sure mijnLevens is decremented. Currently, mijnLevens is always 10.
Change this:
do
{
Zwakmonster zwakmonster = new Zwakmonster();
To this
Zwakmonster zwakmonster = new Zwakmonster();
do
{
So that you don't create a new object for every iteration.
Allan Elder already gave the right answer, to make things less complicated i would use only one var for your lives count
class Zwakmonster : IMonster
{
private string mijnNaam;
private string mijnKleur;
private int lives = 10;
public string Naam
{
get { return mijnNaam; }
set { mijnNaam = value; }
}
public string Kleur
{
get { return mijnKleur; }
set { mijnKleur = value; }
}
public int Levens
{
get { return lives; }
}
public void Hit()
{
lives = lives - 1;
}
}
mijnLevens will always have the value 10.
You need to assign the reduced value back to mijnLevens
I'm trying stuff with db4o since a few days but I got a problem.
Imagine this class just for test:
class Test
{
public string TestString
public int Number;
public Bitmap Bm;
public Test2 T2;
}
I'm saving the entire class and all sub-objects.
But when I load it, I don't want Bm to be loaded (just leave it null). How can I leave it out?
I need to save it because in some cases, I need to load it.
It's a performance thing because the pictures are really large.
Well, the easiest solution (IMHO) is to wrap the BitMap class in another class and use db4o's transparent activation feature:
using System;
using System.IO;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Activation;
using Db4objects.Db4o.TA;
namespace ActivationDepth
{
class Program
{
static void Main(string[] args)
{
var dbFilePath = Path.GetTempFileName();
using (var db = Db4oEmbedded.OpenFile(dbFilePath))
{
db.Store(new C1 { Name = "c1", Huge = new MyHugeClass("I am really huge....")});
}
var config = Db4oEmbedded.NewConfiguration();
config.Common.Add(new TransparentActivationSupport());
config.Common.ActivationDepth = 0;
using (var db = Db4oEmbedded.OpenFile(config, dbFilePath))
{
var item = db.Query<C1>().ElementAt(0);
Console.WriteLine("{0}", db.Ext().IsActive(item));
Console.WriteLine("[Huge] {0} : {1}", db.Ext().IsActive(item.huge), item.huge);
Console.WriteLine("[Huge] {0} : {1}", db.Ext().IsActive(item.Huge), item.Huge);
}
}
}
class C1 : IActivatable
{
public string Name
{
get
{
Activate(ActivationPurpose.Read);
return name;
}
set
{
Activate(ActivationPurpose.Write);
name = value;
}
}
public MyHugeClass Huge
{
get
{
Activate(ActivationPurpose.Read);
return huge;
}
set
{
Activate(ActivationPurpose.Write);
huge = value;
}
}
public override string ToString()
{
Activate(ActivationPurpose.Read);
return string.Format("[{0}] {1}", GetType().Name, name);
}
public void Bind(IActivator activator)
{
if (this.activator != null && activator != null)
{
throw new Exception("activation already set");
}
this.activator = activator;
}
public void Activate(ActivationPurpose purpose)
{
if (activator != null)
{
activator.Activate(purpose);
}
}
public MyHugeClass huge;
private string name;
[NonSerialized]
private IActivator activator;
}
class MyHugeClass : IActivatable
{
public string Name
{
get
{
Activate(ActivationPurpose.Read);
return name;
}
set
{
Activate(ActivationPurpose.Write);
name = value;
}
}
public MyHugeClass(string name)
{
this.name = name;
}
public override string ToString()
{
Activate(ActivationPurpose.Read);
return string.Format("[{0}] {1}", GetType().Name, name);
}
public void Bind(IActivator activator)
{
if (this.activator != null && activator != null)
{
throw new Exception("activation already set");
}
this.activator = activator;
}
public void Activate(ActivationPurpose purpose)
{
if (activator != null)
{
activator.Activate(purpose);
}
}
private string name;
[NonSerialized]
private IActivator activator;
}
}
Note that even though I have implemented the IActivatable interface manually I don't recommend that; you can use db4otool to implement it for you automatically.
Another possible solution is to control activation for your type (when an object is not activated in db4o, its reference is valid but all of its fields will be not initialized taking no space whatsoever).
For instance you can do something like:
using System;
using System.IO;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Events;
namespace ActivationDepth
{
class Program
{
static void Main(string[] args)
{
var dbFilePath = Path.GetTempFileName();
using (var db = Db4oEmbedded.OpenFile(dbFilePath))
{
db.Store(new C1 { name = "c1", c2 = new C2("c2"), huge = new MyHugeClass("I am really huge....")});
}
var config = Db4oEmbedded.NewConfiguration();
using (var db = Db4oEmbedded.OpenFile(config, dbFilePath))
{
var activate = false;
var fac = EventRegistryFactory.ForObjectContainer(db);
fac.Activating += (sender, eventArgs) =>
{
if (!activate && eventArgs.Object.GetType() == typeof(MyHugeClass))
{
Console.WriteLine("[{0}] Ignoring activation.", eventArgs.Object);
eventArgs.Cancel();
}
else
{
Console.WriteLine("[{0}] Activation will proceed.", eventArgs.Object);
}
};
var item = db.Query<C1>().ElementAt(0);
Console.WriteLine("[IsActive] {0}", db.Ext().IsActive(item.huge));
activate = true;
db.Activate(item.huge, 3);
Console.WriteLine("[IsActive] {0}", db.Ext().IsActive(item.huge));
}
}
}
class C1
{
public string name;
public C2 c2;
public MyHugeClass huge;
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, name);
}
}
class C2
{
public string name;
public C2(string name)
{
this.name = name;
}
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, name);
}
}
class MyHugeClass
{
public string text;
public MyHugeClass(string text)
{
this.text = text;
}
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, text);
}
}
}
You can also play with activation depth.
Hope this help.