CodeFluent returns null for a geography column - codefluent

My model contains the following entity:
<Address>
<Id />
<SpatialLocation cfps:dataType="geography" typeName="Microsoft.SqlServer.Types.SqlGeography, Microsoft.SqlServer.Types"/>
</Address>
I have added the following partial class to the business layer:
public partial class Address
{
// The geography spatial data type, geography, represents data in a round-earth coordinate system and has a default SRID value of 4326.
private static readonly int SpatialReferenceIdentifier = 4326;
public void SetPoint(double latitude, double longitude)
{
this.SpatialLocation = SqlGeography.Point(latitude, longitude, SpatialReferenceIdentifier);
}
public double Latitude
{
get
{
return this.SpatialLocation == null ? 0 : this.SpatialLocation.Lat.Value;
}
}
public double Longitude
{
get
{
return this.SpatialLocation == null ? 0 : this.SpatialLocation.Long.Value;
}
}
}
I have added the Nuget package Microsoft.SqlServer.Types to the businesslayer project.
My console application contains the following code:
SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);
Address address = new Address();
address.SetPoint(40, 50);
address.Save();
Console.WriteLine("Latitude: {0}", address.Latitude.ToString());
Console.WriteLine("Longitude: {0}", address.Longitude.ToString());
Address address2 = Address.LoadByEntityKey(address.EntityKey);
Console.WriteLine("Latitude: {0}", address2.Latitude.ToString());
Console.WriteLine("Longitude: {0}", address2.Longitude.ToString());
The output of this console application is:
40
50
0
0
The SpatialLocation is not null in the database. However, the following line of code in the produced ReadRecord method returns null:
this._spatialLocation = ((Microsoft.SqlServer.Types.SqlGeography)(persistence.GetReaderValueObject(reader, "Address_SpatialLocation", default(Microsoft.SqlServer.Types.SqlGeography), typeof(Microsoft.SqlServer.Types.SqlGeography), CodeFluent.Runtime.PersistenceSerializationMode.Default)));
I have added assemblyPaths to the project node but that does not solve the problem.
<cf:project assemblyPaths="..\LIB\Microsoft.SqlServer.Types.dll" ...>
Why does CodeFluent not load the SpatialLocation in the ReadRecord method?
What does the assemblyPaths attribute do? Does CodeFluent need this? Why?
Do I need to call the LoadNativeAssemblies in my console application?

Why does CodeFluent not load the SpatialLocation in the ReadRecord method?
You should check the first chance exception in the output window, because the ReadRecord method swallows exceptions. There are many reasons for not being able to read the value. In your case, I think this is a mismatch of version that you can fixed using a bindingRedirect:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.SqlServer.Types" culture="neutral" publicKeyToken="89845dcd8080cc91"/>
<bindingRedirect oldVersion="10.0.0.0" newVersion="14.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Don't hesitate to post the content of the output window, if you think there is another reason.
What does the assemblyPaths attribute do? Does CodeFluent need this? Why?
CodeFluent Entities resolves the typeName at build time. This is required to generate the right ReadXXXValue. Thus, if you are using a dotnet type which is not in the GAC, you need to add a reference to generate the right code.
Do I need to call the LoadNativeAssemblies in my console application?
You shouldn't not need to call the LoadNativeAssemblies in a console app. However, you must check the dll Microsoft.SqlServer.Types in the bin directory.
BTW, there was a blog post on http://blog.codefluententities.com but the site seems to be down. You can find an offline version of this post (maybe not up to date) on OneDrive: https://1drv.ms/w/s!AkYmf2ZXtwX4gfA27FKegjJgz5PB8g

Related

Implement validator in Eclipse

I am trying to implement validation in Eclipse. My work has many little projects that serve to customize our product for various customers. Since there are a ton of developers we are trying to find a way to enforce various standards and best practices.
For example, we have many XML configurations that we want to validate. The built-in validators ensure files are well-formed and follow a schema, but we would like to add validations such as checking that a Java class referenced in XML actually exists on the classpath. Another example is validating that a Java class implementing a certain interface does not have any object variables (i.e. the code needs to operate only on parameters and not maintain state).
It appears that there are two ways to add validation. The first is through a builder which adds markers. The second is through stand-alone validation. However, we are not actually building anything, and I have not found any useful tutorials or examples on validation (does not help that help.eclipse.org is currently being moved and is unavailable).
When I right-click a test project and select "validate" I get a message stating there was an error during validation, and my test message does not show up in the problem view. However, there are no errors in the Eclipse log. The host Eclipse shows nothing in the console. No exceptions logged anywhere, and no message. The project does have the required custom nature.
I was following these instructions but there is no code or fully functioning example, and Google has not been kind enough to fill in the blanks. Combined with the Eclipse help site being down right now, I am at a loss as to how to proceed.
plugin.xml:
<plugin>
<extension name="My Validator" point="org.eclipse.wst.validation.validator"
id="com.mycompany.pluginname.validator.MyValidator">
<validator>
<projectNature id="com.mycompany.pluginname.nature.MyNature"/>
<helper class="org.eclipse.wst.validation.internal.operations.WorkbenchContext"/>
<markerId markerIdValue="com.mycompany.pluginname.validator.DefaultMarker"/>
<run class="com.mycompany.pluginname.validation.validator.MyValidator"/>
<runStrategy project="true"/>
</validator>
</extension>
<extension point="org.eclipse.core.resources.markers" name="My Validator"
id="com.mycompany.pluginname.validator.DefaultMarker">
<super type="org.eclipse.core.resources.problemmarker"/>
<persistent value="true"/>
<attribute name="owner"/>
<attribute name="validationSeverity"/>
<attribute name="targetObject"/>
<attribute name="groupName"/>
<attribute name="messageId"/>
</extension>
</plugin>
Validator code:
package com.mycompany.pluginname.validation.validator;
import org.eclipse.core.resources.IProject;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.provisional.core.*;
import com.mycompany.pluginname.validation.plugin.ValidationPlugin;
#SuppressWarnings("restriction")
public class MyValidator
implements IValidator {
#Override
public void cleanup(IReporter argReporter) {
argReporter.removeAllMessages(this);
}
#Override
public void validate(IValidationContext argContext, IReporter argReporter)
throws ValidationException {
String bundle = ValidationPlugin.getDefault().getTranslationsBundleName();
IProject prj = ((IWorkbenchContext) argContext).getProject();
String[] attributes =
new String[] {"owner", "validationSeverity", "targetObject", "groupName", "messageId"};
IMessage msg = new Message(bundle, IMessage.HIGH_SEVERITY, "test", attributes, prj);
argReporter.addMessage(this, msg);
}
}
I also find it odd that adding validation would require using restricted packages and interfaces. It also seems odd that it wants an IMessage rather than an IMarker.
I did look at Eclipse plugin with custom validation which seems to be oriented around creating a new editor, where I want to validate files regardless of the editor used (in fact I do not want to create an editor).
Edit: I updated to use the V2 framework, but nothing appears in the problem view. What am I doing wrong? Is there a tutorial somewhere that explains how this works? I was able to figure out the following, but obviously it is not correct:
public ValidationResult validate(ValidationEvent argEvent, ValidationState argState,
IProgressMonitor argMonitor) {
final IResource resource = argEvent.getResource();
final ValidationResult result = new ValidationResult();
try {
List<String> contents = Resources.readFile((IFile) resource);
for (int i = 0; i < contents.size(); ++i) {
int offset = contents.get(i).indexOf("bad_string");
if (offset >= 0) {
result.add(ValidatorMessage.create("Found bad string", resource));
result.incrementError(1);
}
}
}
catch (Exception ex) {
result.add(ValidatorMessage.create(ex.getMessage(), resource));
}
return result;
}
I admit this is a stab in the dark: the documentation is not very descriptive and I have not found any tutorials on this V2 validator. Oh, I have a filter on this validator so it only receives specific XML files, which is why there is no input validation.
Also, since I am a pedant myself, I am using the old-style for loop there because I expect to show the line number with the error to the user. But obviously I am not quite there yet.
Another edit: here is the working code. The only issue is the squiggly is not on the correct line because the offset is from the start of the file, not the line. But it does work:
public ValidationResult validate(ValidationEvent argEvent, ValidationState argState,
IProgressMonitor argMonitor) {
final IResource resource = argEvent.getResource();
final ValidationResult result = new ValidationResult();
try {
List<String> contents = Resources.readFile((IFile) resource);
int location = 0;
for (int i = 0; i < contents.size(); ++i) {
int offset = contents.get(i).indexOf(CONSTANT);
if (offset >= 0) {
ValidatorMessage vm = ValidatorMessage.create("Message", resource);
vm.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
vm.setAttribute(IMarker.SOURCE_ID, IMarker.PROBLEM);
vm.setAttribute(IMarker.LINE_NUMBER, i + 1);
vm.setAttribute(IMarker.CHAR_START, location + offset);
vm.setAttribute(IMarker.CHAR_END, location + offset + CONSTANT.length());
result.add(vm);
}
// TODO: account for different line endings.
location += (line.length() + 2);
}
}
catch (Exception ex) {
ValidationPlugin.getDefault().warn(ex);
result.add(ValidatorMessage.create(ex.toString(), resource));
}
return result;
}
Plugin.xml:
<extension name="My Validator" point="org.eclipse.wst.validation.validatorV2"
id="com.company.plugin.validation.validator.MyValidator">
<validator class="com.company.plugin.validation.validator.MyValidator">
<include>
<rules>
<file type="file" name="FileName.xml"/>
</rules>
</include>
</validator>
</extension>
I actually found another SO question along these lines that corroborates what I found: Setting IMarker.CHAR_START and IMarker.CHAR_END attributes for IMarkers Annotations
sigh that document is very out of date. You should use the org.eclipse.wst.validation.validatorV2 extension point, extending the newer org.eclipse.wst.validation.AbstractValidator class.

NLog config file to get configuration setting values from a web.config

Is there a method to get a value from the <ApplicationSettings> section of a web.config within NLog layout variables?
I already store SMTP details within my web.config and don't want to duplicate the settings just to use within my NLog.config.
Ideally I'd like to do something like: ${aspnet-config:SmtpHostServer}
which then fetches the value from the web.config
I couldn't see any obvious way to do this other than creating my own LayoutRenderer (see below). If you're putting into your own assembly don't forget to add the following into your NLog.Config:
<extensions>
<add assembly="YOURASSEMBLYNAMEHERE" />
</extensions>
Hope this helps someone else:
[LayoutRenderer("aspnet-config")]
public class AspNetConfigValueLayoutRenderer : LayoutRenderer
{
[DefaultParameter]
public string Variable
{
get;
set;
}
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
if (this.Variable == null)
{
return;
}
HttpContext context = HttpContext.Current;
if (context == null)
{
return;
}
builder.Append(Convert.ToString(System.Configuration.ConfigurationManager.AppSettings[this.Variable], CultureInfo.InvariantCulture));
}
}
Updated Answer
NLog ver. 4.6 includes ${appsetting:SmtpHostServer} in the core NLog-nuget-package. No longer requires NLog.Extended. See also https://github.com/nlog/NLog/wiki/AppSetting-Layout-Renderer
NLog.Extensions.Logging ver. 1.4 includes ${configsetting} that allows one to read settings from appsettings.json. See also https://github.com/NLog/NLog/wiki/ConfigSetting-Layout-Renderer
Original Answer
Nowadays this is possible without custom code:
Use NLog.Extended and use
${appsetting:SmtpHostServer}.
See docs for ${appsetting}
Please note: this isn't supported in .NET Core / .NET standard yet.

Reporting Services with Entity Framework

I am using SQL Reporting services to hit a WCF web service.
My query is:
<Query>
<Method Name="GetADTHistory" Namespace="http://tempuri.org/">
<Parameters>
<Parameter Name="personId"><DefaultValue>7885323F-DE8D-47E5-907D-2991C838FF3E</DefaultValue></Parameter>
</Parameters>
</Method>
<SoapAction>
http://tempuri.org/IResidentServiceFrontEnd/GetADTHistory
</SoapAction>
</Query>
My implementation is
public List<ResidentDataTypes.Person> GetADTHistory(Guid personId)
{
using (ResidentDataTypes.MyEntities entity = new ResidentDataTypes.MyEntities ())
{
var person = (from a in entity.People.Include("ResidentAdts")
where a.PersonId == personId
select a);
if (person.Count() > 0)
{
return person.ToList();
}
else
{
return new List<Person>();
}
}
}
This works fine if there are 2 or more ADT records. Reporting services correctly sees all the fields in the database. However if there is only 1 ADT record reporting services sees the 'Person' columns but none of the ADT records. Any ideas?
It looks like that you have an eager/lazy load issue. I suggest you to execute and test the query with linqpad to check if it really includes the ResidentAdts in the case of single record.
I also recommend you to check this thread: Linq to Entities Include Method Not Loading
Adding the "Linq" tag to your question would also helpful.

MEF Contrib Provider Model Not Importing Parts

I have been trying to use the configurable provider model for handling my MEF imports and exports from MEF Contrib (link). I've read the Codeplex documentation and Code Junkie's blog post (link); however, I can't seem to get the container to create the parts. Where am I going wrong?
Program.cs
namespace MEFTest
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
// [ImportMany("command", typeof(IHelp))]
public IEnumerable<IHelp> Commands { get; set; }
void Run()
{
Compose();
foreach(IHelp cmd in Commands)
{
Console.WriteLine(cmd.HelpText);
}
Console.ReadKey();
}
void Compose()
{
var provider = new ConfigurableDefinitionProvider("mef.configuration");
var catalog = new DefinitionProviderPartCatalog<ConfigurableDefinitionProvider>(provider);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
TestCommand.cs
namespace MEFTest
{
//[Export("command", typeof(IHelp))]
public class TestCommand : IHelp
{
private string _helpText = "This is a test.";
public string CommandName
{
get { return "Test"; }
}
public string HelpText
{
get { return _helpText; }
}
}
}
App.Config section:
<mef.configuration>
<parts>
<part type="MEFTest.TestCommand, MEFTest">
<exports>
<export contract="IHelp" />
</exports>
</part>
<part type="MEFTest.Program, MEFTest">
<imports>
<import member="Commands" contract="IHelp" />
</imports>
</part>
</parts>
</mef.configuration>
I don't get any build errors and it runs fine if I switch to the typical attribute-based system that is part of the MEF core (with the appropriate catalog too). Program.Commands is always NULL in the above example. I tried to just use a singular property instead of a collection and get the same results.
When I debug I can get the provider.Parts collection so I know it's accessing the configuration information correctly; however, I get an InvalidOperationException whenever I debug and try to drill into catalog.Parts.
Anyone have any experience as to where I'm going wrong here?
As documented here, you also need this in your config file:
<configSections>
<section
name="mef.configuration"
type="MefContrib.Models.Provider.Definitions.Configurable.PartCatalogConfigurationSection, MefContrib.Models.Provider" />
</configSections>
If you already have that, then it might be interesting to show us the stack trace of the InvalidOperationException that you get when accessing provider.Parts.
I had the same problems and could not get it to work, but here are some details:
It seems that ComposeParts() does not work as expected (at least in the version I used) because it uses static methods, based on Reflection to find all required Imports (so it seems that this part cannot be changed from outside of MEF). Unfortunately we want to use xml configuration and not the MEF attributes.
It works if you add [Import] attributes to the members of the class you you use with ComposeParts(). In your case this would be "Programm". In this case all exports defined in the configuration file will be found.
I could not find any documentation or examples on the MEF Contrib page relating to that problem. Also there is no unittest in the MEF contrib projekt that uses ComposeParts().
A workaround would be to use container.GetExportedValues() to retrieve the values, but in this case you have to set the classes members manually.
Hope that helps.

Can XmlSerializer deserialize into a Nullable<int>?

I wanted to deserialize an XML message containing an element that can be marked nil="true" into a class with a property of type int?. The only way I could get it to work was to write my own NullableInt type which implements IXmlSerializable. Is there a better way to do it?
I wrote up the full problem and the way I solved it on my blog.
I think you need to prefix the nil="true" with a namespace in order for XmlSerializer to deserialise to null.
MSDN on xsi:nil
<?xml version="1.0" encoding="UTF-8"?>
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="array">
<entity>
<id xsi:type="integer">1</id>
<name>Foo</name>
<parent-id xsi:type="integer" xsi:nil="true"/>
My fix is to pre-process the nodes, fixing any "nil" attributes:
public static void FixNilAttributeName(this XmlNode #this)
{
XmlAttribute nilAttribute = #this.Attributes["nil"];
if (nilAttribute == null)
{
return;
}
XmlAttribute newNil = #this.OwnerDocument.CreateAttribute("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance");
newNil.Value = nilAttribute.Value;
#this.Attributes.Remove(nilAttribute);
#this.Attributes.Append(newNil);
}
I couple this with a recursive search for child nodes, so that for any given XmlNode (or XmlDocument), I can issue a single call before deserialization. If you want to keep the original in-memory structure unmodified, work with a Clone() of the XmlNode.
The exceptionally lazy way to do it. It's fragile for a number of reasons but my XML is simple enough to warrant such a quick and dirty fix.
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");