Using Function from a class in API Class - c#

I want to set some data in an API class by calling a function from another class.
Why the 'main' has error while 'Classes' works? How and where I should define it?
Error: a field initializer cannot reference the nonstatic field
How do I can get the ID which has passed in URL to use in my class?
This is my code:
public class InformationController : ApiController
{
Classes main = new Classes();
Information[] Information = new Information[]
{
new Information { Info_ID = 2, fullName = main.getFullname("2"), },
};
public IEnumerable<Information> GetAllInformation()
{
return Information;
}
public Information GetInformationById(int id)
{
var information = Information.FirstOrDefault((p) => p.Info_ID == id);
if (information == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return information;
}
public IEnumerable<Information> GetInformationByCategory(string category)
{
return Information.Where(
(p) => string.Equals(p.std_nextClass, category,
StringComparison.OrdinalIgnoreCase));
}
}

You can try initialize the array in the constructor:
public class InformationController : ApiController
{
private Classes main = new Classes();
private Information[] Information;
public InformationController()
{
Information = new Information[]
{
new Information { Info_ID = 2, fullName = main.getFullname("2"), },
};
}
/// the rest of your code...

Related

How to map a class A that inherits from base class using AutoMapper in c#

I have a class GetData
public class GetData
{
public FooClass PrevData {get;set;}
public FooClass NewData {get;set;}
}
public class FooClass: Class B{}
public class B
{
public string varC;
public string varD;
public string varE;
}
I need to use automapper to map class GetData's PrevDataA's fields to Class C's properties. I will then use class C to store data in database.
public class C
{
public Data data {get;set;}
public string var_e;
}
public class Data
{
public string var_c;
public string var_d;
}
I have tried these two :
CreateMap<GetData,C>()
.ConvertUsing(src => src.PrevData.Select (x => new C
{
var_e = x.varE;
varData= new Data()
{
var_c = varC;
var_d = varD;
}}));
}
Here I get an error on 'select' that testClass does not contain definition for 'Select'.
Also, I have tried using below:
.ForMember(dest => dest.Data.var_c, src => src.MapFrom(src.PrevData.VarC))
This is also giving an error saying :
Expression "dest => dest.Data.var_C" must resolve top level member and not any child's properties. You can Forpath, a custom resolver on the childtype or the AfterMap option instead.
Can anyone help in using ForPath or this.
You can specify the mapping for the properties/fields C.data and C.var_e manually with the ForMember() configuration of CreateMap(). The configuration can look like this:
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<GetData, C>()
.ForMember(dest => dest.var_e, i => i.MapFrom(src => src.PrevData.varE))
.ForMember(dest => dest.data, i => i.MapFrom(src => new Data
{
var_c = src.PrevData.varC,
var_d = src.PrevData.varD
}));
});
This will say that for the target C.var_e field, use the value of src.PrevData.varE. And for the C.data field, create a new Data instance with the filled var_c and var_d fields with values from src.PrevData.varC and src.PrevData.varD.
See the following example:
GetData getData = new GetData {
NewData = new FooClass {
varC = "newData_C",
varD = "newData_D",
varE = "newData_E"
},
PrevData = new FooClass {
varC = "prevData_C",
varD = "prevData_D",
varE = "prevData_E"
}
};
C target = mapper.Map<C>(getData);
Console.WriteLine(target.var_e);
if (target.data != null)
{
Console.WriteLine(target.data.var_c);
Console.WriteLine(target.data.var_d);
}
else
{
Console.WriteLine("target.data is NULL");
}
This will generate the following output:
prevData_E
prevData_C
prevData_D

Why am I getting an error while running this code?

When I was running a console application, I got this stack overflow error.
As this error seems to be in the Assignlogic part of my code, I have wrote down that part of code and the error which is shown. My question is how to handle this exception, without changing the functionality of code?
//Assign
public class Assignlogic
{
private List<Assign> Assigns { get; set; } = new List<Assign>();//Here exception unhandled was thrown
//System.StackOverflowException: 'Exception of type 'System.StackOverflowException' was thrown.'
readonly Assignlogic logicC = new Assignlogic();
public void AddEmployeetoProject(Assign assign, Employeelogic logicA, Projectlogic logicB)
{
List<Employee> Employes = logicA.Employees;
List<Project> Projcts = logicB.Projects;
List<Assign> Assignss = logicC.Assigns;
var id = assign.EmpId;
var pid = assign.PID;
var emp = Employes.Find(a => a.EmpId == id);
var prjct = Projcts.Find(c => c.PID == pid);
if (emp != null || prjct != null)
{
Assignss.Add(assign);
}
}
//view all assigned projects
public List<Assign> GetAllAssignedProjects()
{
return Assigns;
}
//remove an employee from a project
public void RemoveEmployee(string id)
{
var emp = Assigns.Find(a => a.EmpId == id);
if (emp != null)
{
Assigns.Remove(emp);
}
}
public bool SearchProjectbyMappedId(string id)
{
var employee = Assigns.Find(c => c.EmpId == id);
if (employee != null)
{
return true;
}
else
{
return false;
}
}
}
What happens when you create an instance of Assignlogic? This:
readonly Assignlogic logicC = new Assignlogic();
So creating an instance of Assignlogic creates an instance of Assignlogic, which creates an isntance of Assignlogic, which creates an instance of Assignlogic, etc., etc.
I don't know what your intent is here, but this is clearly not the way to do it. Objects shouldn't recursively create themselves ad infinitum.
you have this member in your class AssignLogic
readonly Assignlogic logicC = new Assignlogic();
So when you create an AssignLogic, it has to go and create an AssignLogic to put there. Creating that AssignLogic requires another AssignLogic,.......

How to disable discriminator field in MongoDb (C# driver)

Is there a way to disable completely (for all classes) the discriminator ("_t") fields from being added to the bson documents?
I am referring to: mongo-csharp-driver/polymorphism
Let's say we have a Square and Rectangle that inherit from Shape.
public abstract class Shape
{
public ObjectId Id { get; set; }
}
public sealed class Square : Shape
{
public int Size { get; set; }
}
public sealed class Rectangle : Shape
{
public int Width { get; set; }
public int Height { get; set; }
}
Like you said if we run the following code.
var client = new MongoClient();
var db = client.GetDatabase("test");
var shapes = db.GetCollection<Shape>("shapes");
await shapes.InsertManyAsync(new Shape[]
{
new Square{Size = 10},
new Rectangle{Height = 5, Width = 4}
});
We'll get the following inserted into MongoDB
db.shapes.find()
{ "_id" : ObjectId("5f4e2affc23dde5a501bdf0b"), "_t" : "Square", "Size" : 10 }
{ "_id" : ObjectId("5f4e2affc23dde5a501bdf0c"), "_t" : "Rectangle", "Width" : 4, "Height" : 5 }
Initially, I thought we'd be able to set the DiscriminatorIsRequired flag on the BsonClassMap and wrap that in a convention, however, from trying this it seems to fail due to the following bit of logic in the MongoDB C# Driver.
private bool ShouldSerializeDiscriminator(Type nominalType)
{
return (nominalType != _classMap.ClassType || _classMap.DiscriminatorIsRequired || _classMap.HasRootClass) && !_classMap.IsAnonymous;
}
https://github.com/mongodb/mongo-csharp-driver/blob/9e567e23615c8bb5c7ac1489427c2d15b2124522/src/MongoDB.Bson/Serialization/Serializers/BsonClassMapSerializer.cs#L722
So because there's no way for us to tell the serializer we don't want to include a discriminator we'll have to give it a convention instead that does nothing.
If we create an IDiscriminatorConvention that pretty much does nothing and returns back null for the discriminator then the driver won't add this to the document.
public class NullDiscriminatorConvention : IDiscriminatorConvention
{
public static NullDiscriminatorConvention Instance { get; }
= new NullDiscriminatorConvention();
public Type GetActualType(IBsonReader bsonReader, Type nominalType)
=> nominalType;
public BsonValue GetDiscriminator(Type nominalType, Type actualType)
=> null;
public string ElementName { get; } = null;
}
This discriminator convention then needs to be registered against each type.
BsonSerializer.RegisterDiscriminatorConvention(typeof(Square), NullDiscriminatorConvention.Instance);
BsonSerializer.RegisterDiscriminatorConvention(typeof(Rectangle), NullDiscriminatorConvention.Instance);
Alternately if we want it on all types you could do a little bit of reflection.
var shapeTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(domainAssembly => domainAssembly.GetTypes(),
(domainAssembly, assemblyType) => new {domainAssembly, assemblyType})
.Where(t => #t.assemblyType.IsSubclassOf(typeof(Shape)))
.Select(t => #t.assemblyType).ToArray();
foreach (var shapeType in shapeTypes)
{
BsonSerializer.RegisterDiscriminatorConvention(shapeType, NullDiscriminatorConvention.Instance);
}
Now if we re-run our code.
var shapeTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(domainAssembly => domainAssembly.GetTypes(),
(domainAssembly, assemblyType) => new {domainAssembly, assemblyType})
.Where(t => #t.assemblyType.IsSubclassOf(typeof(Shape)))
.Select(t => #t.assemblyType).ToArray();
foreach (var shapeType in shapeTypes)
{
BsonSerializer.RegisterDiscriminatorConvention(shapeType, NullDiscriminatorConvention.Instance);
}
var client = new MongoClient();
var db = client.GetDatabase("test");
var shapes = db.GetCollection<Shape>("shapes");
await shapes.InsertManyAsync(new Shape[]
{
new Square{Size = 10},
new Rectangle{Height = 5, Width = 4}
});
we'll get our expected output.
db.shapes.find()
{ "_id" : ObjectId("5f4e2d63ed12d7c5d3638d36"), "Size" : 10 }
{ "_id" : ObjectId("5f4e2d63ed12d7c5d3638d37"), "Width" : 4, "Height" : 5 }
One option is using Newtonsoft bson serializer (Newtonsoft.Json.Bson) which gives a lot of serialization options.
It isn't efficient since you need to write the bson to a stream and then read it from there with MongoDb reader but it provides lots of customization option.
Example code:
class BsonDocBuilder
{
private readonly MemoryStream _memStream = new MemoryStream();
private readonly JsonSerializerSettings _serializeSettings = new JsonSerializerSettings();
private readonly JsonSerializer _jsonSerializer;
public BsonDocBuilder()
{
_jsonSerializer = JsonSerializer.Create(_serializeSettings);
}
public BsonDocument ToBson<T>(T value)
{
BsonDocument bd;
try
{
using (BsonDataWriter dataWriter = new BsonDataWriter(_memStream))
{
dataWriter.CloseOutput = false;
_jsonSerializer.Serialize(dataWriter, value);
}
bd= BsonSerializer.Deserialize<BsonDocument>(_memStream.ToArray());
}
finally
{
_memStream.SetLength(0);
}
return bd;
}
}

Public class is inaccessible due to protection level; Constructor is public

I have a class that is public, ArticleDao, but when I try to use it in another file, it says "ArticleDao is inaccessible due to its protection level." Here is the entire class:
class ArticleDao : IArticleDao
{
private readonly ContentManager _contentManager;
private static readonly char[] DelimiterChars = { '|', '\n' };
private const int ArticlePagingSize = 500;
public ArticleDao()
{
_contentManager = new ContentManager();
}
private Image GetImage(XElement element)
{
var image = new Image();
if (String.IsNullOrEmpty((String)element))
{
return image;
}
XElement imageElement = element.Element("img");
if (imageElement != null)
{
image.Url = (String)imageElement.Attribute("src");
}
return image;
}
private Link GetLink(XElement element)
{
var link = new Link();
if (String.IsNullOrEmpty((String)element))
{
return link;
}
XElement anchorElement = element.Element("a");
if (anchorElement != null)
{
link.Url = (String)anchorElement.Attribute("href");
link.Text = (String)anchorElement;
}
return link;
}
public Article GetArticle(long id, string html)
{
var a = new Article();
long testid = 556;
if (id == testid)
{
var x = 1;
}
XDocument xdoc = XDocument.Parse(html);
var xElement = xdoc.Element("root");
if (xElement != null)
{
XElement articleElem = xElement.Element("Event");
if (articleElem != null)
{
a = new Article();
a.Id = id.ToString(CultureInfo.InvariantCulture);
a.Title = (String)articleElem.Element("Title");
a.PublishedDate = GetDateTime((String)articleElem.Element("PublishedDate"));
a.SubHeader = (String)articleElem.Element("SubHeader");
a.Image = GetImage(articleElem.Element("Image"));
a.Caption = (String)articleElem.Element("Caption");
a.Body = (String)articleElem.Element("Body");
a.Url = GetLink(articleElem.Element("Url"));
}
}
return a;
}
public Article GetArticle(Int64 ektronContentId)
{
var item = _contentManager.GetItem(ektronContentId);
return GetArticle(ektronContentId, item.Html);
}
public IEnumerable<Article> GetArticles(Int64 folderId)
{
int count;
IEnumerable<Article> articles = new List<Article>(ArticlePagingSize);
do
{
var criteria = new ContentCriteria();
criteria.AddFilter(ContentProperty.FolderId, CriteriaFilterOperator.EqualTo, folderId);
criteria.PagingInfo.RecordsPerPage = ArticlePagingSize;
var articleContentData = _contentManager.GetList(criteria);
count = articleContentData == null ? 0 : articleContentData.Count;
articles = articles.Concat(_contentManager.GetList(criteria)
.Select(i => GetArticle(i.Id, i.Html)));
} while (count == ArticlePagingSize);
return articles;
}
private DateTime GetDateTime(string date)
{
DateTime dt;
DateTime.TryParse(date, out dt);
return dt;
}
}
The constructor is public. I even tried replacing all instances of "private" with "public," but it still says that it is inaccessible. This is the line where I'm trying to invoke it:
private static IArticleDao _articleDao;
public static IArticleDao ArticleDao
{
get { return _articleDao ?? (_articleDao = new ArticleDao()); }
}
Where it says "_articleDao = new ArticleDao()" is where the error is.
I'm especially confused because to create ArticleDao and IArticleDao, I essentially just copied EventDao and IEventDao and replaced "Event" with "Article." This works:
private static IEventDao _eventDao;
public static IEventDao EventDao
{
get { return _eventDao ?? (_eventDao = new EventDao()); }
}
but ArticleDao does not work.
The class itself isn't public. It's internal. (The default accessibility for anything is the smallest legal accessibility option, which for a non-nested class, is internal. You have specified no accessibility option explicitly.)
You class ArticleDao is a internal, as if you don't specify any accessibility modifier, the default in C# is internal. To resolve this issue you may think of declaring it public
public class ArticleDao : IArticleDao
{
...
}
The class' default access level is internal. Internal types or members are accessible only within files in the same assembly.
You probably want to specify
public class ArticleDao...
The constructor accessibility is not the same as the class access level, and if something is hidden by the class access modifier you cannot access any of its members regardless of their access modifier.

Writing a Workflow Foundation workflow with C#

I'm trying to write some activities with C# instead of the designer and XAML. VS2010 has been buggy and very slow for that, and it also has very poor compilation support (for variables names, properties and so on).
So I'm trying to create activities by inheriting from the Activity class directly, but I'm encountering a snag.
Here's my code:
public class TestActivity : Activity
{
public InArgument<string> Username { get; set; }
public InArgument<string> Password { get; set; }
public OutArgument<bool> ValidCredential { get; set; }
public OutArgument<ProvisioningRole> Role { get; set; }
public OutArgument<Guid> Guid { get; set; }
protected override Func<Activity> Implementation
{
get
{
return () =>
{
return new Sequence()
{
Activities =
{
new AuthenticateUserActivity()
{
Username = this.Username,
Password = this.Password,
Guid = this.Guid,
Result = this.ValidCredential
},
new If()
{
Condition = this.ValidCredential,
Then = new GetUserRoleActivity()
{
Username = this.Username,
Password = this.Password,
Result = this.Role
}
},
}
};
};
}
set { base.Implementation = value; }
}
}
The problem is with the If(), the condition. It's supposed to be an InArgument, but this.ValidCredential is an OutArgument. I've tried creating a Variable, assign the value of ValidCredential to it. I also tried to put the result of AuthenticateUserActivity in the variable and then assign it to ValidCredential, but I get an error saying the To property of Assign needs to be specified.
I've looked around for proper tutorials, but all I found was an MSDN article that had a quick and dirty code implementation, and it used literals instead of the passed arguments, so no help from there.
I found out how to do it. You just need to create new InArgument from the original one. There is a constructor that takes an expression for it.
Username = new InArgument<bool>((ActivityContext c) => this.ValidCredential.Get(c))
So I changed my whole activity to
return new CompensableActivity()
{
Body = new Sequence()
{
Activities =
{
new AuthenticateUserActivity()
{
Username = this.Username.In(),
Password = this.Password.In(),
Guid = this.Guid.Out(),
Result = this.ValidCredential.Out()
},
new If(this.ValidCredential.In())
{
Then = new GetUserRoleActivity()
{
Username = this.Username.In(),
Password = this.Password.In(),
Result = this.Role.Out()
},
Else = new Assign<ProvisioningRole>()
{
To = this.Role.Out(),
Value = ProvisioningRole.User
}
}
}
},
};
In and Out being extension methods I wrote:
public static class WorkflowExtensions
{
#region In
public static InArgument<T> In<T>(this InArgument<T> self)
{
return new InArgument<T>(context => self.Get(context));
}
public static InArgument<T> In<T>(this OutArgument<T> self)
{
return new InArgument<T>(context => self.Get(context));
}
#endregion
#region Out
public static OutArgument<T> Out<T>(this InArgument<T> self)
{
return new OutArgument<T>(context => self.Get(context));
}
public static OutArgument<T> Out<T>(this OutArgument<T> self)
{
return new OutArgument<T>(context => self.Get(context));
}
#endregion
}
And now all is well!
You should be able to get this to work. The basic approach should be to use a Variable to store data, use an OutArgument to get data out of activities into the Variable and InArguments to get data from a Variable into an activity.
Also note that the expressions to tie InArguments to Variables are VisualBasicValue expressions. So something like:
Condition = new VisualBasicValue("System.DateTime.Now.Hour < 12")
This blog post isn't about using arguments and variables but shows a couple of examples.
Going to shamelessly plug my own library that I ended up making for this:
http://code.google.com/p/system-transactions/
Allows basic compensation of code without the ginormous hassle of WF. Also, compiles properly and is easily debuggable.

Categories

Resources