CSVHelper generic ClassMap with System.Reflection - .net-core

I'm trying genericly map the properties of my class to the column names of the CSV without the need to write every single line in the ClassMap like
Map(rm => rm.PUsrCrRequestedObject).Name("#P_USR_CR_RequestedObject");
because we have very much columns with mostly the same type of mapping.
So i tried the following code:
var classMap = csv.Configuration.AutoMap<RequestMonitoring>();
foreach (var property in typeof(RequestMonitoring).GetProperties())
{
var columnName = property.Name switch
{
"PNdsPn" => "$P_NDS_PN",
{ } x when x.StartsWith("PUsrCr") => property.Name.Replace("PUsrCr", "#P_USR_CR_"),
_ => property.Name
};
classMap.Map(requestMonitoring => property).Name(columnName);
}
I don't get an error but if i debug the ClassMap the code above hasn't got any effect.
So the question is how can i fix the code snippet or if it's not possible maybe how to apply the same name conversion for every property

Try this.
classMap.Map(typeof(RequestMonitoring), property).Name(columnName);

Related

Adding new MediaType to NewtonsoftJsonInputFormatter doesn't work

I'd like to add a new MediaType to the MvcOptions input formatter in .Net 5
When I do the following
services.AddControllers();
services.Configure<Microsoft.AspNetCore.Mvc.MvcOptions>(options =>
{
options.InputFormatters
.OfType<Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter>()
.First()
.SupportedMediaTypes
.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/csp-report"));
});
everything works fine. But I want to use Newtonsoft.Json instead of the default Json-Serializer so I changed my code to
services.AddControllers()
.AddNewtonsoftJson();
services.Configure<Microsoft.AspNetCore.Mvc.MvcOptions>(options =>
{
options.InputFormatters
.OfType<Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonInputFormatter>()
.First()
.SupportedMediaTypes
.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/csp-report"));
});
But now every time a application/csp-report is send to the controller I get a 415 Status code.
The AddNewtonsoftJson method will add two input formatters (NewtonsoftJsonInputFormatter and NewtonsoftJsonPatchInputFormatter) and when you are calling the OfType both are returning, but because you are selecting the first one, that will be always NewtonsoftJsonPatchInputFormatter that ended up being configured with your new media type not the NewtonsoftJsonInputFormatter that you expected.
So as a possible fix the code could be like:
.AddNewtonsoftJson();
services.Configure<Microsoft.AspNetCore.Mvc.MvcOptions>(options =>
{
options.InputFormatters
.OfType<Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonInputFormatter>()
.First(f => !(f is Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonPatchInputFormatter))
.SupportedMediaTypes
.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/csp-report"));
});
All information here: Adding new MediaType to NewtonsoftJsonInputFormatter doesn't work

Load object from RavenDB

I'm trying to do some refactoring on a project. I want to replace the code between the lines and with the two commented lines above it so I can use it on another page where I need the quote object
//quote.LoadActive();
//QuoteID = quote.Id;
//--------------------------------------------------------
List<Quote> DBquotes = session.Query<Quote>()
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.ToList();
foreach (Quote q in DBquotes)
{
if (q.IsActive)
{
QuoteID = q.Id;
quote = session.Load<Quote>(q.Id);
}
}
//--------------------------------------------------------
Here's the LoadActive() function inside the Quote class
public Quote LoadActive()
{
List<Quote> DBquotes = session.Query<Quote>()
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.ToList();
foreach (Quote q in DBquotes)
if (q.IsActive)
return session.Load<Quote>(q.Id);
return new Quote();
}
But I don't know how to actually update the quote object. I can't update inside the function without doing it element by element and that's too tedious. If I try and do quote = quote.LoadActive() then it complains that quote hasn't been initialized. I'm sure there's a way to set up what I'm trying to do but I'm blanking and can't think of good keywords to google my question. I couldn't even come up with a good subject wording for this post!
EDIT: tl;dr I need to load the active quote into the 'quote' object to be used by the page. What's in between the lines works, I want to replace all with the commented lines above (or something similar).
You're Quote object should not be responsible for accessing the database. You should be using some Data Access class or even better yet, a Query Handler to access the DB.
I think you might be a little confused as to what the code is doing. Let me try to explain.
public Quote LoadActive()
{
//This call returns every Quote Document in the DB
//RavenDB by default will only return a Max of 128 w/out doing paging
List<Quote> DBquotes = session.Query<Quote>()
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.ToList();
//This doesn't make any sense. You're saying the first quote that is active,
//make another expensive DB call and return the same object.
//I still don't know what you want to do, but you already have the quote object
//why would you go to the DB and get something that you already have?
foreach (Quote q in DBquotes)
if (q.IsActive)
return session.Load<Quote>(q.Id);//Unnecessary, you have the Quote already
//return q;
return new Quote(); //if there's no active quotes just return an Empty Quote Object
}
Are you trying to return all Active Quotes from the DB?
You can do this
var activeQuotes = session.Query<Quote>()
.Where(x => x.IsActive == true)
.ToList();//Remember, RavenDB's safe by default feature
//will only return 128 records, you have to
//implement paging
If you are trying to just return the first IsActive quote (which is what it looks like you want to do from your code) you can simply do:
public Quote LoadActive()
{
return session.Query<Quote>()
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.FirstOrDefault(x => x.IsActive);
}
Edit based on comment:
This will allow you to accomplish what you want by
QuoteId = quote.LoadActive().Id;

Modifying/Injecting CSS Style sheets in GeckoFX

I am trying to manipulate Style Sheets through:
GeckoFXWebBrowser.Document.StyleSheets
as mentioned here, but clearing or adding any rules as mentioned there throwing exceptions related to JSContext, also I tried to use nsIStyleSheetService similarly to what mentioned here as follows:
Dim SSS = Gecko.Xpcom.CreateInstance(Of Gecko.nsIStyleSheetService)("#mozilla.org/content/style-sheet-service;1")
Dim mUri = Gecko.IOService.CreateNsIUri("myCSSUri")
SSS.LoadAndRegisterSheet(mUri, Gecko.nsIDOMWindowUtilsConsts.USER_SHEET)
But this also throwing ambigious COM related exception.
I tried all this in DocumentCompleted event.
Any ideas what is wrong here? or how to accomplish task? (GeckoFX 29)
Since the FAQ entry was written Firefox has had some security changes which is prolly the cause of the initial exceptions.
Check out the Geckofx 29 unittests here in particular :
[Test]
public void GetCssRules_DoesNotThrowException()
{
GeckoStyleSheet styleSheet = _browser.Document.StyleSheets.First();
GeckoStyleSheet.StyleRuleCollection cssRules = null;
Assert.DoesNotThrow(() => { cssRules = styleSheet.CssRules; });
Assert.DoesNotThrow(() => { cssRules.Insert(0, "#blanc { color: white }"); });
Assert.DoesNotThrow(() => { cssRules.RemoveAt(0); });
Assert.DoesNotThrow(() => { cssRules.Clear(); });
}
As for the second method using nsIStyleSheetService:
Dim mUri = Gecko.IOService.CreateNsIUri("myCSSUri")
Is likely to work better if you specify a valid uri. (eg. http://www.google.com)

Cannot implicitly convert type 'System.Linq.IQueryable to System.Data.Entity.DbSet<>

I receive the following error when I try to run my code. I haven't managed to solve it yet, please Help:
edit: Marked with * where it fails.
>
public IQueryable<Video> GetVideos([QueryString("id")] int? categorieId)
{
var _db = new TeleviziuneAcademicaAspSilverlight.Models.VideoContext();
IQueryable<Video> query = *_db.Videos;*
if (categorieId.HasValue && categorieId > 0)
{
query = query.Where(v => v.CategorieID == categorieId);
}
return query;
Change
IQueryable<Video> query =
to
IQueryable<Appname.Models.Video> query =
The reason for your error is that you have the type Video defined twice and because of using a short type name you accidentally reference not the one Video you should.
Also change it in the method's return value
public IQueryable<Appname.Models.Video> GetVideos( ... )
You seem to have two classes called Video. If you need both, you'll need to project from one to the other before your return statement:
return query.Select(dbVideo => new Appname.Video()
{
Prop1 = dbVideo.Prop1,
Prop2 = dbVideo.Prop2,
// etc.
});
Though you'll probably need to change the return type to an IEnumerable<> if you do that.
If you can just work with Appname.Models.Video, change IQueryable<Video> to IQueryable<Appname.Models.Video> in the method signature and the method body.

Moq Example using out and ref needed

I am trying to build a test against some legacy method that implement out parameters.
Could you give me an example how to do this?
Just assign the out or ref parameter from the test.
Given this interface:
public interface ILegacy
{
bool Foo(out string bar);
}
You can write a test like this:
[TestMethod]
public void Test13()
{
string bar = "ploeh";
var legacyStub = new Mock<ILegacy>();
legacyStub.Setup(l => l.Foo(out bar))
.Returns(true);
Assert.IsTrue(legacyStub.Object.Foo(out bar));
Assert.AreEqual("ploeh", bar);
}
Anything wrong with the second example at the top of https://github.com/moq/moq4/wiki/Quickstart ? You really should be giving examples of what you're trying to do if you're not going to look for things like this.
Incidentally if you want to use moq (currently) to mock the out parameter too you'll also have to do the following hoop jump. Lets say that you wanted to mock an out parameter that returned another mocked object e.g.
var mockServiceA = new Mock<IMyService>();
var mockServiceOutput = new Mock<IMyServiceOutput>();
// This will not work...
mockServiceA.Setup(svc => svc.DoSomething(out mockServiceOutput.Object));
// To have this work you have to do the following
IMyServiceOutput castOutput = mockServiceOutput.Object;
mockServiceA.Setup(svc => svc.DoSomething(out castOutput));

Resources