C# Problems with XML Serialization - c#

i have a problem with a webservice but i don´t see the error. I have used a wsdl to generate the Web Reference in VS2017. This is the class which was generated:
https://gist.github.com/meteora1986/b43c9750ddeb50187420edd6741301f5
When using this class the xml used for the webservice is not generated with the XMLAttributes-options. While debugging i discoverd following errors by the XMLImporter:
errors
So i tried to serialize it to get a more detailed error message with code like
try
{
var serializer = new XmlSerializer(typeof(ari_webserviceService));
}
catch (Exception ex)
{
// codes
}
And got from from the exeption these messages:
1. inner Message: There was an error reflecting field 'Site'.
2. inner MessageThere was an error reflecting type 'System.ComponentModel.ISite'.
But these fields or types aren´t used in the webservice class? Can anybody help?

I have absolutly no idea of web-services in general.
But your webservice is derived from SoapHttpClientProtocol. If you go up the base-classes by HttpWebClientProtocol and WebClientProtocol to finally end with Component you'll see the property Component.Site.
You might be able to solve your problem if you implement the IXmlSerializable interface to have full control what (and how) you want to serialize the data...

Related

C# vs PowerShell. How to get detailed exception info?

I'm using some external library though COM interface.
I have generic class for that.
Database.Connector connector = new Database.Connector();
string connectString = "srvr=nonexisthost;database=test;"; // bogus connect string
try
{
var database = connector.Connect(connectString);
}
catch (COMException ex)
{
Console.WriteLine(ex.Message);
}
Trying to build a error proof logic I intentionally provoke an exception.
And I have discovered that C# COMException contains only generic info, like:
Error HRESULT E_FAIL has been returned from a call to a COM component.
while executing samey code in PowerShell results in more detailed description:
$connector = New-Object -ComObject Database.Connector
$connectString = "srvr=nonexisthost;database=test;"
$database = $connector.Connect($connectString)
Error while executing transaction with an information base
server_addr=nonexisthost descr=11001(0x00002AF9): Host is unknown.
line=1048 file=src\DataExchangeCommon.cpp
My question is: what should I do in order to get same error info in C# (if it is possible)?
I'm not a COM Interop expert but I'll try to answer what I know and hope it will help you.
From the managed side
If the HRESULT is recognized by the runtime (CLR), the runtime automatically creates a specific managed exception for the error (e.g. FileNotFoundException). Otherwise, the runtime creates a generic COMException object which says "I don't know what this HRESULT meaning".
If the unmanaged code provides error info, you will see it in the ErrorCode property, otherwise, you will see just the HRESULT code.
You can try to search for this code (google\github) to obtain more info.
From the unmanaged side
You need to implement ISupportErrorInfo and IErrorInfo interfaces to provide more info.
So to answer your question, in C#, you can't get more info in the COMException object if this info is not provided.
For more info:
COMException, Handling COM Interop Exceptions, IErrorInfo, ISupportErrorInfo, HRESULT's mapping, Common HRESULT values

Runtime casting of COM objects in C#

I am working on a application which needs to communicate via COM interface with multiple CAD applications (not in the same time). I want to have nice and reusable code, but I came across problems with type casting of COM objects when I made generic application handle getter method.
What I tried so far:
This is the attempt I would like the most if it worked.
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
//Here under Dynamic View/Message there is already an error
// Message = "Element not found. (Exception from HRESULT: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))"
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = (TCadAppType)Marshal.GetActiveObject(cadVersion.Value);
//Following 2 lines of code are for testing purposes only, i am testing with Solidworks API
AssemblyDoc Assembly;
//The exception is thrown when I try to access some method from the Solidworks API
Assembly = (AssemblyDoc)cadApp.OpenDoc6("some parametras...");
}
Attempt using Convert class
// Another attempt using Convert class
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = Marshal.GetActiveObject(cadVersion.Value);
cadApp = Convert.ChangeType(cadApp, typeof(SldWorks.SldWorks));
// Exception is thrown with the following message:
// Message = "Object must implement IConvertible."
}
I really thought that I am on the right track, since there is an article on Microsoft Docs website explaining how dynamic can help you with com interopt: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic#com-interop
Any ideas how I can do this runtime casting a keep my code as reusable as possible?
My software setup:
Win 10
Project is targeted for .NET 4.7.2
First Tests are with Solidworks 2019
Turns out that the my coding attempt 1 was valid c# code indeed.
I tried it using with Autodesk Inventor, and it works.
So the only thing left for me is to conclude that this is some bug from Solidworks and their COM interfacing.
Thank you Optional Option for your interest in the topic.

How can I retrieve the LoaderExceptions property from the Exception class? [duplicate]

I get a error message while updating my service reference:
Custom tool warning: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
How can I retrieve the LoaderException property?
Update: My errors went away when I reimported the domain object projects. I have no idea why this fixed the issue, but I'm happy it's working.
try
{
// load the assembly or type
}
catch (Exception ex)
{
if (ex is System.Reflection.ReflectionTypeLoadException)
{
var typeLoadException = ex as ReflectionTypeLoadException;
var loaderExceptions = typeLoadException.LoaderExceptions;
}
}
catch (ReflectionTypeLoadException ex)
{
foreach (var item in ex.LoaderExceptions)
{
MessageBox.Show(item.Message);
}
}
I'm sorry for resurrecting an old thread, but wanted to post a different solution to pull the loader exception (Using the actual ReflectionTypeLoadException) for anybody else to come across this.
Using Quick Watch in Visual Studio you can access the LoaderExceptions from ViewDetails of the thrown exception like this:
($exception).LoaderExceptions
Another Alternative for those who are probing around and/or in interactive mode:
$Error[0].Exception.LoaderExceptions
Note: [0] grabs the most recent Error from the stack

C#: How to create custom exception from ValidationEventArgs exception, when validating an XML using XSD

I have an XML file that is validated against an XSD file.
When a validation exception occurs, the handler is called:
ValidationCallBack(object sender, System.Xml.Schema.ValidationEventArgs args)
I have the exception thrown by the framework, but I need to customize this exception in order to have the XSD line that have thrown this error and also the value from the XML that was not correct.
Can I parse the exception's message in order to extract this kind of information? I mean, can I rely on a regular expression for this?
You can get this information from Exception member.
static void ValidationCallback(object sender, ValidationEventArgs args)
{
// Not sure if the exception is guaranteed to not be null.
if (args.Exception != null)
{
// Remember to always retain the InnerException (last argument is args.Exception).
throw new MyException(args.Exception.LineNumber, args.Exception.LinePosition, args.Exception.Message, args.Exception);
}
// If the exception is null do what we can.
throw new MyException(-1, -1, args.Message, args.Exception);
}
EDIT: Just noticed that you wanted the original element/thing that caused the problem. Firstly, you can get the schema entity that caused the validation problem from SchemaObject. Getting the original item that caused the problem is way more difficult. You are probably going to have to re-read the document (with a non-validating reader) and search for the node with the matching line/position.
Side note: Please don't use regex, ever. You will get really nasty problems if your application is run on another locale: as all the built-in .Net exceptions have translations (so your regex won't work).
You can find the details of the validation exception by looking at the public properties of the XmlSchemaException class (the instances of which are available via the Exception property of the args argument):
LineNumber
LinePosition
SourceSchemaObject
I have found the solution, by using the xmlns:ex="anySchemaNamespace" attribute for the xsd document element. Then, I can add for example this unhandled attribute ex:exception="My custom exception" to any element and then take that custom exception message from the element in code, when an exception occurs.
Thanks for your answers.

Why can't I use the 'AccessDeniedException' namespace?

I get the message that the namespace can't be found when I use the code below. Where does the AccessDeniedException live?
try { ... }
catch (SomeKindOfException ex)
{
MessageBox.Show(ex.Message);
}
catch (AccessDeniedException ex)
{
//Do something else
}
Thanks
I don't think that's the exception you're looking for. The only one with this name (that I can find) is in a Sharepoint namespace. Try attaching the debugger and seeing exactly what the type of the thrown exception is.
The type of the exception is going to vary depending on your context. So for example, if it's an "access denied" when trying to open a file, it could be a FileLoadException, or something similar. If it's encountered because of Code Access Security, it will be SecurityException. And so on.
You may need to give the full namespace on the exception, or have a using statement at the top of your code file so .NET knows where to find the exception you're talking about. If that doesn't work, maybe you need to add the DLL that contains that exception to the "REFERENCES" list in your project.

Categories