Issue in using Code in C# interact with mongodb - c#

My Code is following :
try
{
MongoDatabase mtest1 = mongoServer.GetDatabase("ews", mC);
MongoCollection<EliteGuard> ecollection1 = mtest1.GetCollection<EliteGuard>("EliteGuard");
int intC = FindUser(comboBox1.Text.ToString());
int intCount = 0;
foreach (EliteGuard t in ecollection1.FindAll())
{
if (t.product_key.Equals(comboBox1.Text.ToString()))
{
intCount++;
}
}
if (intC <= intCount)
{
MessageBox.Show("Total no. of Serial Key is generated.", "Elite Manager Information", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
catch (MongoConnectionException mcex)
{
MessageBox.Show("Unable to connect to Server. Please try Again.", "Elite Manager Information", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (Exception ex)
{
return;
}
Error :
An error occurred while deserializing the product_key property of
class Serial_Key_Generation.Form5+EliteGuard: Input string was not in
a correct format.
StackTrace : at
MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMember(BsonReader
bsonReader, Object obj, BsonMemberMap memberMap) at
MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader
bsonReader, Type nominalType, Type actualType,
IBsonSerializationOptions options) at
MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader
bsonReader, Type nominalType, IBsonSerializationOptions options) at
MongoDB.Bson.Serialization.BsonSerializer.Deserialize(BsonReader
bsonReader, Type nominalType, IBsonSerializationOptions options) at
MongoDB.Driver.Internal.MongoReplyMessage1.ReadFrom(BsonBuffer
buffer, IBsonSerializationOptions serializationOptions) at
MongoDB.Driver.Internal.MongoConnection.ReceiveMessage[TDocument](BsonBinaryReaderSettings
readerSettings, IBsonSerializationOptions serializationOptions) at
MongoDB.Driver.MongoCursorEnumerator1.GetReply(MongoConnection
connection, MongoRequestMessage message) at
MongoDB.Driver.MongoCursorEnumerator1.GetFirst() at
MongoDB.Driver.MongoCursorEnumerator1.MoveNext() at
Serial_Key_Generation.Form5.comboBox1_SelectedIndexChanged(Object
sender, EventArgs e) in D:\Projects\Serial Key Generation\Serial Key
Generation\Form5.cs:line 94
But the same type of code is working properly on another Form.

An error occurred while deserializing the product_key property of
class Serial_Key_Generation.Form5+EliteGuard: Input string was not in
a correct format.
There is an inconsistency between the implementation of the EliteGuard class and your database data. The product_key property in that class does not match its equivalent in the database. It's possible you defined it as the wrong data type in your class definition. It seems to be expecting a string but it's not getting one. You'll need to change the data type of product_key either in the class definition or in the DB (class definition is probably easier).
But the same type of code is working properly on another Form.
That doesn't really tell me much. Are you loading data from the same DB & collection and are you using the same class? It's hard to answer this without more information. In any case it sounds like something is different, because it's not having trouble deserializing there. Try stepping through the code in each scenario and see what is different from one form to the other. It may just be a small difference that you overlooked. Having a separate working example should make it easier to see what is wrong with the form that doesn't work.

Yes that is connecting same database and code is the same from another Form.

Related

Protobuf de-serializing exception "A repeated type was not expected as an aux type"

When trying to deserialize an observablecollection, it gives me an exception
**"
"An exception of type 'System.NotSupportedException' occurred in protobuf-net.Core.dll but was not handled in user code
Additional information: A repeated type was not expected as an aux type:""**
public Task<T> ReceiveDataAsync<T>(TcpClient client)
{
using (NetworkStream stream = new NetworkStream(client.Client, false))
{
return Task.FromResult(Serializer.DeserializeWithLengthPrefix<T>(stream, PrefixStyle.Fixed32));
}
}
I haven't found details about this exception at all.
The WithLengthPrefix API expects a single message, not a collection. Maybe serialize something that has a collection.

Serialization error with firebase on Unity

I'm trying to run a transaction with realtime database to change an object, with the following code :
void tryBeHost()
{
string path = "weeks/" + week + "/games/" + gameId + "/gameInfo";
_dbRef.Child(path).RunTransaction(mutableData =>
{
GameInfo gameInfo = mutableData.Value as GameInfo;
if (gameInfo == null)
{
gameInfo = new GameInfo();
}
else if (gameInfo.host != null && gameInfo.host != myId)
{
return TransactionResult.Success(mutableData);
}
gameInfo.host = myId;
mutableData.Value = gameInfo;
return TransactionResult.Success(mutableData);
});
}
so I'm getting this weird error :
Exception in transaction delegate, aborting transaction
Firebase.Database.DatabaseException: Failed to parse object Serializables.GameInfo ---> System.ArgumentException: Invalid type Serializables.GameInfo for conversion to Variant
at Firebase.Variant.FromObject (System.Object o) [0x001df] in Z:\tmp\tmp.EaS8iXpRBh\firebase\app\client\unity\proxy\Variant.cs:117
at Firebase.Database.Internal.Utilities.MakeVariant (System.Object value) [0x00000] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\Utilities.cs:25
--- End of inner exception stack trace ---
at Firebase.Database.Internal.Utilities.MakeVariant (System.Object value) [0x0000d] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\Utilities.cs:27
at Firebase.Database.MutableData.set_Value (System.Object value) [0x00000] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\MutableData.cs:136
at InternetShit.b__10_0 (Firebase.Database.MutableData mutableData) [0x00045] in /Users/sandukhan/Unity/projects/Ronda/Assets/Scripts/InternetShit.cs:73
at Firebase.Database.Internal.InternalTransactionHandler.DoTransaction (System.Int32 callbackId, System.IntPtr mutableData) [0x00022] in
Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\InternalTransactionHandler.cs:49
UnityEngine.Debug:LogWarning(Object)
Firebase.Platform.FirebaseLogger:LogMessage(PlatformLogLevel, String) (at Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseLogger.cs:92)
Firebase.LogUtil:LogMessage(LogLevel, String) (at Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/LogUtil.cs:68)
Firebase.Database.Internal.InternalTransactionHandler:DoTransaction(Int32, IntPtr) (at Z:/tmp/tmp.sZ8vrpcx53/firebase/database/client/unity/proxy/InternalTransactionHandler.cs:51)
Firebase.AppUtilPINVOKE:PollCallbacks()
Firebase.AppUtil:PollCallbacks() (at Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/AppUtil.cs:32)
Firebase.Platform.FirebaseAppUtils:PollCallbacks() (at Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/FirebaseAppUtils.cs:33)
Firebase.Platform.FirebaseHandler:Update() (at Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseHandler.cs:205)
Firebase.Platform.FirebaseMonoBehaviour:Update() (at Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseMonoBehaviour.cs:45)
my GameInfo Class is the following :
using System;
using Serializables;
namespace Serializables
{
[Serializable]
public class GameInfo
{
public string gameId;
public string host;
public string[] playersIds;
public string[] playersPics;
public string[] playersNames;
}
}
if anyone has an idea to solve this I will be grateful
I think you figured out the basics: You can only submit bool, string, long, double, IDictionary, and List<Object> to Value.
There's some interesting notes that I'd like to layer on top of this though! I like to use Unity's JsonUtility in conjunction with SetRawJsonValueAsync and GetRawJsonValue from GetValueAsync. Your code will look a bit like this:
async void SendGameInfo(string path, GameInfo info) {
try {
await _database
.GetReference(path)
.SetRawJsonValueAsync(JsonUtility.ToJson(info));
Debug.Log($"Successfully wrote {info}");
} catch (AggregateException e) {
Debug.LogWarning($"Failed with {e}");
}
}
async Task<GameInfo> ReadGameInfo(string path) {
try {
var dataSnapshot = await _database
.GetReference(path)
.GetValueAsync();
return JsonUtility.FromJson<GameInfo>(info);
} catch (AggregateException e) {
Debug.LogWarning($"Failed with {e}");
return null;
}
}
Also, if you can, having spent time digging through the library I like to consider IDictionary<string, object> the "basic primitive" of Realtime Database. This will be used as an intermediary format when you set RawJson if you step through the disassembly. Also, since Transactions don't provide access to raw json, this will give you a more uniform interface to RTDB (unless your data looks like an array, then your primitive is List<object> - "looks like" meaning that your keys are numbers and the range of numbers RTDB is aware of is about half full).
Of course, the team actively monitors the quickstart github page and you can use the new "feature request" template to request a change to any of this if it will help 😃.
I think RTFM always works, I found out that there are specific types that are accepted for mutableData.Value : bool, string, long, double, IDictionary and List{Object} where Object is one of previously listed types. So I got this error because my class GameInfo is not accepted and I have to convert my object to an IDictionary.
source : https://firebase.google.com/docs/reference/unity/class/firebase/database/mutable-data#class_firebase_1_1_database_1_1_mutable_data_1a4833f23246b3079078332d57c5649254

HelloWorld example for sending an object over RabbitMQ via EasyNetQ between two different applications

Hi I am attempting to send a simple object like through RabbitMQ via EasyNetQ. I'm having issues deserializing that object on the subscription side. Anyone able to show me a sample of how this works. Keep in mind the object being sent is defined in it's own project and not shared among the publisher and subscriber. Here is my sample, and perhaps you can tell me what is wrong with it?
Program A:
class ProgramA
{
static void Main(string[] args)
{
using (var bus = RabbitHutch.CreateBus("host=localhost"))
{
Console.WriteLine("Press any key to send the message");
Console.ReadKey();
bus.Publish(new MessageA { Text = "Hello World" });
Console.WriteLine("Press any key to quit");
Console.ReadKey();
}
}
public class MessageA
{
public string Text { get; set; }
}
}
Program B:
class ProgramB
{
static void Main(string[] args)
{
using (var bus = RabbitHutch.CreateBus("host=localhost"))
{
bus.Subscribe<MessageB>("", HandleClusterNodes);
Console.WriteLine("Press any key to quit");
Console.ReadKey();
}
}
private static void HandleClusterNodes(MessageB obj)
{
Console.WriteLine(obj.Text);
}
[Queue("TestMessagesQueue", ExchangeName = "EasyNetQSample.ProgramA+MessageA:EasyNetQSample")]
public class MessageB
{
public string Text { get; set; }
}
}
Here is the error I'm receiving:
DEBUG: HandleBasicDeliver on consumer: f9ded52d-039c-411a-9b9f-5c8ee3301854, deliveryTag: 1
DEBUG: Received
RoutingKey: ''
CorrelationId: 'ec41faea-a0c8-4ffd-8163-2cbf85d45fcd'
ConsumerTag: 'f9ded52d-039c-411a-9b9f-5c8ee3301854'
DeliveryTag: 1
Redelivered: False
ERROR: Exception thrown by subscription callback.
Exchange: 'EasyNetQSample.ProgramA+MessageA:EasyNetQSample'
Routing Key: ''
Redelivered: 'False'
Message:
{"Text":"Hello World"}
BasicProperties:
ContentType=NULL, ContentEncoding=NULL, Headers=[], DeliveryMode=2, Priority=0, CorrelationId=ec41faea-a0c8-4ffd-8163-2cbf85d45fcd, ReplyTo=NULL, Expiration=NULL, MessageId=NULL, Timestamp=0, Type=EasyNetQSample.ProgramA+MessageA:EasyNetQSample, UserId=NULL, AppId=NULL, ClusterId=NULL
Exception:
System.AggregateException: One or more errors occurred. ---> EasyNetQ.EasyNetQException: Cannot find type EasyNetQSample.ProgramA+MessageA:EasyNetQSample
at EasyNetQ.TypeNameSerializer.DeSerialize(String typeName)
at EasyNetQ.DefaultMessageSerializationStrategy.DeserializeMessage(MessageProperties properties, Byte[] body)
at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass19.<Consume>b__18(Byte[] body, MessageProperties properties, MessageReceivedInfo messageReceivedInfo)
at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass1e.<Consume>b__1d(Byte[] body, MessageProperties properties, MessageReceivedInfo receviedInfo)
at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecutionContext context)
--- End of inner exception stack trace ---
---> (Inner Exception #0) EasyNetQ.EasyNetQException: Cannot find type EasyNetQSample.ProgramA+MessageA:EasyNetQSample
at EasyNetQ.TypeNameSerializer.DeSerialize(String typeName)
at EasyNetQ.DefaultMessageSerializationStrategy.DeserializeMessage(MessageProperties properties, Byte[] body)
at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass19.<Consume>b__18(Byte[] body, MessageProperties properties, MessageReceivedInfo messageReceivedInfo)
at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass1e.<Consume>b__1d(Byte[] body, MessageProperties properties, MessageReceivedInfo receviedInfo)
at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecutionContext context)<---
What do I need to do to be able to properly deserialize MessageA?
As far as I know, the default setting of the EasyNetQ requires the type of the serialized object to be consistent between applications. For example, you can send any known .NET type easily like String:
bus.Publish<String>("Excellent.");
and it will be happy on both projects.
You can use your own Message if you put it to a common library (dll). Since you specially mentioned that they reside in different projects, I'd suggest to serialize and cast objects yourself.
EasyNetQ uses interally Newtonsoft Json.NET to serialize objects like this. As you can see, your message has been serialized already as:
Message: {"Text":"Hello World"}
To do this yourself, you still need to add a reference to Json.NET because EasyNetQ hides this reference by using ilrepack.
This should work:
bus.Publish<string>(JsonConvert.SerializeObject(new MessageA { Text = "Hello World" }));
and
bus.Subscribe<string>("", HandleClusterNodes);
private static void HandleClusterNodes(string obj)
{
var myMessage = (MessageB)JsonConvert.DeserializeObject<MessageB>(obj);
Console.WriteLine(myMessage.Text);
}
But you'll lose your attribute based routing with this and might want to modify your methods.
If you want to keep using basic methods, you can set topic with like this:
bus.Publish<string>(JsonConvert.SerializeObject(new MessageA { Text = "Hello World" }), "topic.name");
bus.Subscribe<string>("", HandleClusterNodes, new Action<EasyNetQ.FluentConfiguration.ISubscriptionConfiguration>( o => o.WithTopic("topic.name")));
But to have complete control, you need to use Advanced API;
var yourMessage = new Message<string>(JsonConvert.SerializeObject(new MessageA { Text = "Hello World" }));
bus.Advanced.Publish<string>(new Exchange("YourExchangeName"), "your.routing.key", false, false, yourMessage);
and on the subscriber part:
IQueue yourQueue = bus.Advanced.QueueDeclare("AnotherTestMessagesQueue");
IExchange yourExchange = bus.Advanced.ExchangeDeclare("YourExchangeName", ExchangeType.Topic);
bus.Advanced.Bind(yourExchange, yourQueue, "your.routing.key");
bus.Advanced.Consume<string>(yourQueue, (msg, info) => HandleClusterNodes(msg.Body));
which is the almost same as the original RabbitMQ C# Client API.
Detailed analysis:
The main problem is this exception:
EasyNetQ.EasyNetQException: Cannot find type EasyNetQSample.ProgramA+MessageA:EasyNetQSample
This is thrown by EasyNetQ because it cannot find the special class on the endpoint.
If we look at source code of the TypeNameSerializer.cs, you will see
var type = Type.GetType(nameParts[0] + ", " + nameParts[1]);
if (type == null)
{
throw new EasyNetQException(
"Cannot find type {0}",
typeName);
}
this is where it tried to find EasyNetQSample.ProgramA.MessageA type on second project, while it only knows EasyNetQSample.ProgramB.MessageB.
Alternatively, you can roll out your own custom ISerializer or put an ITypeNameSerializer into the default serializer but I haven't tried this.
Furkan is correct that your problem is that the subscriber needs access to the MessageA type defined by your publisher so that it can deserialize the message to that type. From the EasyNetQ docs
When messages are serialized, EasyNetQ stores the message type name in the Type property of the message properties. This metadata is sent along with your message to any subscribers who can then use it to deserialize the message.
This amounts to a tight shared contract between publisher and consumer. If you want to loosen that up then there are a couple of things you can do:
You can publish and subscribe based on an interface (e.g. IMessage, from which you can derive MessageA). You will still need access to the MessageA type in order to cast the received message, but you can publish and subscribe without specifying a specific derived type.
You can create a single, shared "container" type (e.g. MessageContainer) and then serialize/deserialize your type into an instance of the container type as XML, JSON, whatever. Your subscriber can pull the data out of the container and parse it however it wants to. You could even include a schema or version info in the container header to give some hints to the subscriber about how to parse the data. The point it that they never have to turn it into a defined type and therefore don't need access to a bunch of types, just to the MessageContainer type so they can get at the serialized content.
Class MessageA must be in the scope of both apps
bus.Publish<MessageA>("Excellent.");
Contracts (as domain models "dto", or interfaces where is needed) needs to be in a common library.
Example:
DomainModel library
Person
...
Sender App (reference DomainModel)
Other models...
Send(new Person(){...});
Receiver App (reference DomainModel)
Other models...
Person p = Receive(...);
in this way both ends know the common part of the domain model

C# Reflection exception Method not found

Hi I'm developing CRM 2011 Plugin and I have a problem with reflected type. I have generated Entities classes and I know that property exists in the type but when I try to get its value I'm getting exception about method not being found. The stupidest part is that it works perfectly on my machine but doesn't work on clients.
Here's my code (I need to take all OptionSets from the entity and perform action on them):
public override void MyExecute()
{
var fse = TargetEntity.ToEntity<Equipment>();
Type equiptmentType = fse.GetType();
TracingService.Trace("FSE object type: {0}", equiptmentType.FullName);
IEnumerable<PropertyInfo> optionSetsProperties = equiptmentType.GetProperties()
.Where(x => x.PropertyType == typeof(OptionSetValue)).ToList(); //I'm getting this property from the object type so it must exist.
foreach (var optionSetsProperty in optionSetsProperties)
{
TracingService.Trace("Resolving ResourceGroup on property: {0}", optionSetsProperty.Name);
ResolveResourceGroupBySkill(optionSetsProperty, fse);
TracingService.Trace("Resoloving ResourceGroup finished");
}
}
private void ResolveResourceGroupBySkill(PropertyInfo optionSetsProperty, Equipment fse)
{
try
{
TracingService.Trace("Trying to get value of: {0}", optionSetsProperty.Name);
OptionSetValue skillLevel = (OptionSetValue)optionSetsProperty.GetValue(fse);
TracingService.Trace("Value equals: {0}", skillLevel);
}
catch (Exception ex)
{
TracingService.Trace("An error occured: {0}", ex.Message);
Exception inner = ex;
while (inner != null)
{
TracingService.Trace(inner.Message);
inner = inner.InnerException;
}
throw new InvalidOperationException(String.Format("Cannot get value of skill level from property: {0}", optionSetsProperty.Name), ex);
}
}
Here's the Log details:
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Method not found: 'System.Object System.Reflection.PropertyInfo.GetValue(System.Object)'.Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ErrorCode>-2147220891</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
<KeyValuePairOfstringanyType>
<d2p1:key>OperationStatus</d2p1:key>
<d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">0</d2p1:value>
</KeyValuePairOfstringanyType>
</ErrorDetails>
<Message>Method not found: 'System.Object System.Reflection.PropertyInfo.GetValue(System.Object)'.</Message>
<Timestamp>2014-09-11T12:58:09.2941554Z</Timestamp>
<InnerFault i:nil="true" />
<TraceText>
[OC.CSSFieldService: OC.CSSFieldService.ServiceActivity.MyPlugin]
[424ad2a7-ea29-e411-be7f-00155d0aa109: OC.CSSFieldService.ServiceActivity.MyPlugin: Create of equipment]
FSE object type: OC.Data.Equipment
Resolving ResourceGroup on property: oc_ExpeCommHyper
</TraceText>
</OrganizationServiceFault>
As you can see even the tracing line "Trying to get value of" is not working. The exception is not caught... I don't know what to do. Any thoughts?
Ok I figured it out. The server has Microsft .NET 4.0 installed and I have .NET 4.5.
In the .NET 4.5 there's a new overload for PropertyInfo.GetValue method - it's PropertyInfo.GetValue(object obj) since in 4.0 there is only PropertyInfo.GetValue(object obj, object[] indexer)
I just had to replace:
OptionSetValue skillLevel = (OptionSetValue)optionSetsProperty.GetValue(fse);
with
OptionSetValue skillLevel = (OptionSetValue)optionSetsProperty.GetValue(fse, null);
worked like a charm!

Asking a Generic Method to Throw Specific Exception Type on FAIL

Right, I know I am totally going to look an idiot with this one, but my brain is just not kicking in to gear this morning.
I want to have a method where I can say "if it goes bad, come back with this type of Exception", right?
For example, something like (and this doesn't work):
static ExType TestException<ExType>(string message) where ExType:Exception
{
Exception ex1 = new Exception();
ExType ex = new Exception(message);
return ex;
}
Now whats confusing me is that we KNOW that the generic type is going to be of an Exception type due to the where clause. However, the code fails because we cannot implicitly cast Exception to ExType. We cannot explicitly convert it either, such as:
static ExType TestException<ExType>(string message) where ExType:Exception
{
Exception ex1 = new Exception();
ExType ex = (ExType)(new Exception(message));
return ex;
}
As that fails too.. So is this kind of thing possible? I have a strong feeling its going to be real simple, but I am having a tough day with the old noggin, so cut me some slack :P
Update
Thanks for the responses guys, looks like it wasn't me being a complete idiot! ;)
OK, so Vegard and Sam got me on to the point where I could instantiate the correct type, but then obviously got stuck because the message param is read-only following instantiation.
Matt hit the nail right on the head with his response, I have tested this and all works fine. Here is the example code:
static ExType TestException<ExType>(string message) where ExType:Exception, new ()
{
ExType ex = (ExType)Activator.CreateInstance(typeof(ExType), message);
return ex;
}
Sweet! :)
Thanks guys!
You can almost do it like this:
static void TestException<E>(string message) where E : Exception, new()
{
var e = new E();
e.Message = message;
throw e;
}
However, that doesn't compile because Exception.Message is read only. It can only be assigned by passing it to the constructor, and there's no way to constrain a generic type with something other than a default constructor.
I think you'd have to use reflection (Activator.CreateInstance) to "new up" the custom exception type with the message parameter, like this:
static void TestException<E>(string message) where E : Exception
{
throw Activator.CreateInstance(typeof(E), message) as E;
}
Edit Oops just realised you're wanting to return the exception, not throw it. The same principle applies, so I'll leave my answer as-is with the throw statements.
The only issue with the solution is that it is possible to create a subclass of Exception which does not implement a constructor with a single string parameter, so the MethodMissingException might be thrown.
static void TestException<E>(string message) where E : Exception, new()
{
try
{
return Activator.CreateInstance(typeof(E), message) as E;
}
catch(MissingMethodException ex)
{
return new E();
}
}
I have been instantiating inline the type of exception I want to throw, like this:
if (ItemNameIsValid(ItemName, out errorMessage))
throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
throw new ArgumentNullException("MyArgument is null");
Have you tried, instead:
static T TestException<Exception>(string message)
{}
because I have a feeling that putting in the generic constraint is not necessary as all throwable exceptions must inherit from System.Exception anyway.
Remember that generics do accept inherited types.
I think seeing as all exceptions should have a parameterless constructor, and have the Message property, so the following should work:
static ExType TestException<ExType>(string message) where ExType:Exception
{
ExType ex = new ExType();
ex.Message = message;
return ex;
}
Edit: OK, Message is read only, so you'll have to hope the class implements the Exception(string) constructor instead.
static ExType TestException<ExType>(string message) where ExType:Exception
{
return new ExType(message);
}

Categories

Resources