This code works by taking a function as a parameter and using try-catch to log the result of the function.
When I change the functionDecorator here, I want the changes to be applied automatically to functionDecorator<T> or functionDecorator<T1, T2> without copying the entire code as it is now
These functions that do almost the same thing Is there a way to manage each other's behavior in one place, including even try-catch statements?
public void funtionDecorator(Func<bool> Func, string successText = "success", string failText = "fail", string errorText = "error")
{
try
{
if (Func())
{
txtStatusBar.Text = successText;
}
else
{
txtStatusBar.Text = failText;
}
}
catch(Exception ex)
{
txtStatusBar.Text = errorText + Func.Method.Name + ex.ToString();
}
}
// ex : funtionDecorator<DataTable>(useDataFuntion, dt);
public void funtionDecorator<T>(Func<T, bool> Func, T type, string successText = "success", string failText = "fail", string errorText = "error")
{
try
{
if (Func(type))
{
txtStatusBar.Text = successText;
}
else
{
txtStatusBar.Text = failText;
}
}
catch (Exception ex)
{
txtStatusBar.Text = errorText + Func.Method.Name + ex.ToString();
}
}
// ex : funtionDecorator<DataTable, Double>(useDataFuntion, dt, value);
public void funtionDecorator<T1, T2>(Func<T1, T2, bool> Func, T1 type1, T2 type2, string successText = "success", string failText = "fail", string errorText = "error")
{
try
{
if (Func(type1, type2))
{
txtStatusBar.Text = successText;
}
else
{
txtStatusBar.Text = failText;
}
}
catch (Exception ex)
{
txtStatusBar.Text = errorText + Func.Method.Name + ex.ToString();
}
}
I tried to handle it dynamically using dynamic, but the function type was not converted to dynamic, so I couldn't find a way.
Related
This question already has answers here:
Ignore a property during xml serialization but not during deserialization
(2 answers)
Memory Leak using StreamReader and XmlSerializer
(6 answers)
How to add XmlInclude attribute dynamically
(4 answers)
Closed 4 years ago.
I have a simple class as a test:
public class TEST
{
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
}
I want to serialize this class to XML, but when I do; I want to specify at runtime how I want to serialize it. Only PropertyOne, only PropertyTwo or both.
I figured out you can achieve it normally by using the [XmlIgnore] attribute on the properties that you don't want to serialize. I then tried the method explained here:
How to add property-level Attribute to the TypeDescriptor at runtime?
But for some reason it simply doesn't work. Here's my code:
TEST testInstance = new TEST();
testInstance.PropertyOne = "One";
testInstance.PropertyTwo = "Two";
SetAttributesToObjectOnProperty(testInstance, "PropertyOne");
using (StringWriter mainStringWriter = new StringWriter())
{
XmlSerializer mainXMLSerializer = new XmlSerializer(testInstance.GetType());
mainXMLSerializer.Serialize(mainStringWriter, testInstance);
string theXMLToWrite = mainStringWriter.ToString();
}
public static void SetAttributesToObjectOnProperty(object classInstanceToCheck, string propertyName)
{
if (propertyName != null && classInstanceToCheck != null)
{
// Prepare the Property Overriding Type Descriptor
PropertyOverridingTypeDescriptor mainPropertyOverridingTypeDescriptor = new PropertyOverridingTypeDescriptor(TypeDescriptor.GetProvider(classInstanceToCheck).GetTypeDescriptor(classInstanceToCheck));
// Iterate through properies in the supplied Object / Type
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(classInstanceToCheck))
{
if (propertyDescriptor.Name == propertyName)
{
System.Xml.Serialization.XmlIgnoreAttribute theXMLIgnoreAttributToAdd = new System.Xml.Serialization.XmlIgnoreAttribute();
PropertyDescriptor newPropertyDescriptor = TypeDescriptor.CreateProperty(classInstanceToCheck.GetType(), propertyDescriptor, theXMLIgnoreAttributToAdd);
// Set the new PropertyOverridingTypeDescriptor to override that property
mainPropertyOverridingTypeDescriptor.OverrideProperty(newPropertyDescriptor);
break;
}
}
// Add the new descriptor provider that will return our descriptor instead of default
TypeDescriptor.AddProvider(new TypeDescriptorOverridingProvider(mainPropertyOverridingTypeDescriptor), classInstanceToCheck);
}
}
public static void SetAttributesToObjectOnProperty(object classInstanceToCheck, string propertyName)
{
try
{
if (propertyName != null)
{
// Prepare the Property Overriding Type Descriptor
PropertyOverridingTypeDescriptor mainPropertyOverridingTypeDescriptor = new PropertyOverridingTypeDescriptor(TypeDescriptor.GetProvider(classInstanceToCheck).GetTypeDescriptor(classInstanceToCheck));
// Iterate through properies in the supplied Object / Type
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(classInstanceToCheck))
{
if (propertyDescriptor.Name == propertyName)
{
System.Xml.Serialization.XmlIgnoreAttribute theXMLIgnoreAttributToAdd = new System.Xml.Serialization.XmlIgnoreAttribute();
PropertyDescriptor newPropertyDescriptor = TypeDescriptor.CreateProperty(classInstanceToCheck.GetType(), propertyDescriptor, theXMLIgnoreAttributToAdd);
// Set the new PropertyOverridingTypeDescriptor to override that property
mainPropertyOverridingTypeDescriptor.OverrideProperty(newPropertyDescriptor);
break;
}
}
// Add the new descriptor provider that will return our descriptor instead of default
TypeDescriptor.AddProvider(new TypeDescriptorOverridingProvider(mainPropertyOverridingTypeDescriptor), classInstanceToCheck);
}
}
catch (Exception ex)
{
MessageBox.Show("Error at 'SetAttributesToObjectOnProperty'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public class PropertyOverridingTypeDescriptor : CustomTypeDescriptor
{
// Fields
private readonly Dictionary<string, PropertyDescriptor> OverridePropertyDescriptors = new Dictionary<string, PropertyDescriptor>();
// Constructor
public PropertyOverridingTypeDescriptor(ICustomTypeDescriptor parent) : base(parent) { }
// Methods
public void OverrideProperty(PropertyDescriptor thePropertyDescriptor)
{
try
{
OverridePropertyDescriptors[thePropertyDescriptor.Name] = thePropertyDescriptor;
}
catch (Exception ex)
{
MessageBox.Show("Error at 'OverrideProperty'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public override object GetPropertyOwner(PropertyDescriptor thePropertyDescriptor)
{
try
{
object toReturn = base.GetPropertyOwner(thePropertyDescriptor);
if (toReturn == null)
{
return this;
}
return toReturn;
}
catch (Exception ex)
{
MessageBox.Show("Error at 'GetPropertyOwner'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
public PropertyDescriptorCollection GetPropertiesMain(PropertyDescriptorCollection thePropertyDescriptorCollection)
{
try
{
List<PropertyDescriptor> mainPropertyDescriptorList = new List<PropertyDescriptor>(thePropertyDescriptorCollection.Count + 1);
foreach (PropertyDescriptor propertyDescriptor in thePropertyDescriptorCollection)
{
if (OverridePropertyDescriptors.ContainsKey(propertyDescriptor.Name))
{
mainPropertyDescriptorList.Add(OverridePropertyDescriptors[propertyDescriptor.Name]);
}
else
{
mainPropertyDescriptorList.Add(propertyDescriptor);
}
}
PropertyDescriptorCollection toReturn = new PropertyDescriptorCollection(mainPropertyDescriptorList.ToArray());
return toReturn;
}
catch (Exception ex)
{
MessageBox.Show("Error at 'GetPropertiesMain'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
public override PropertyDescriptorCollection GetProperties()
{
try
{
return GetPropertiesMain(base.GetProperties());
}
catch (Exception ex)
{
MessageBox.Show("Error at 'GetProperties'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
try
{
return GetPropertiesMain(base.GetProperties(attributes));
}
catch (Exception ex)
{
MessageBox.Show("Error at 'GetProperties'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
}
public class TypeDescriptorOverridingProvider : TypeDescriptionProvider
{
// Fields
private readonly ICustomTypeDescriptor MainCustomTypeDescriptor;
// Constructor
public TypeDescriptorOverridingProvider(ICustomTypeDescriptor theCustomTypeDescriptor)
{
try
{
this.MainCustomTypeDescriptor = theCustomTypeDescriptor;
}
catch (Exception ex)
{
MessageBox.Show("Error at Constructor 'TypeDescriptorOverridingProvider'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// Methods
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
try
{
return MainCustomTypeDescriptor;
}
catch (Exception ex)
{
MessageBox.Show("Error at 'GetTypeDescriptor'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
}
There are no exceptions, it just still serializes both.
I don't know if I'm not using this method correctly or if I'm missing something else here.
I would like to use this method on other bigger classifications and try use other XML Attributes as well.
I'm trying to convert following vb set/get function to c#. It is used through an ActiveX page like :
Item.CtxString(document.getElementById("setvar").value+"1")=document.getElementById("setval").value;
or :
Item.CtxString("var1") = "var";
The following code is used in VB.NET :
Public Property CtxString(ByVal strItemType As String) As String
Get
Try
Return myContext.ContextString(strItemType)
Catch ex As Exception
Return ""
End Try
End Get
Set(ByVal value As String)
Try
myContext.ContextString(strItemType) = value
Catch ex As Exception
End Try
End Set
End Property
Public Sub SetCtxString(ByVal strItemType As String, ByVal value As String)
Try
myContext.ContextString(strItemType) = value
Catch ex As Exception
End Try
End Sub
I'm trying to convert this from VB to C#, with following function :
public string CtxString
{
get
{
return ctxString;
}
set
{
ctxString = value;
}
}
public void SetCtxString(string value)
{
this.ctxString = value;
}
ContextString is a function used in c++, which needs to be converted to c# aswell..
STDMETHODIMP CContextATL::get_ContextString(BSTR strItemType, BSTR *pVal)
{
try
{
_bstr_t strItem(strItemType, true);
_bstr_t strTemp;
char szBuffer[2048] = {0};
CContextItem *pItem = _Module.GetContextItemFromEnvironment(m_strEnv, (char *)strItem);
if(pItem != NULL)
{
strTemp = pItem->GetContextStringValue().c_str();
*pVal = ::SysAllocString(static_cast<const wchar_t*>(strTemp));
sprintf( szBuffer, "ContextString Key = '%s' Value = '%s' read by Client %s with name = %s in Environment %s\r\n", (char *)strItem, (char *)strTemp, m_strId.c_str(), m_strClientName.c_str(), m_strEnv.c_str());
}
else
{
sprintf( szBuffer, "ContextString Key = '%s' not found while reading by Client %s with name = %s in Environment %s\r\n", (char *)strItem, m_strId.c_str(), m_strClientName.c_str(), m_strEnv.c_str());
}
_Module.WriteDebugString(szBuffer);
}
catch(_com_error & e)
{
ATLTRACE("CContextATL::get_ContextString exception : %s\n", e.ErrorMessage());
}
return S_OK;
}
Anyone who could help me out to convert the following function from VB.NET to c#?
The VB property is a "parameterized property" - this is not available in C#, so you would convert this to 2 separate methods:
public string get_CtxString(string strItemType)
{
try
{
return myContext.ContextString(strItemType);
}
catch (Exception ex)
{
return "";
}
}
public void set_CtxString(string strItemType, string value)
{
try
{
myContext.ContextString(strItemType) = value;
}
catch (Exception ex)
{
}
}
Your original 'set' method is now redundant:
public void SetCtxString(string strItemType, string value)
{
try
{
myContext.ContextString(strItemType) = value;
}
catch (Exception ex)
{
}
}
How about this? C# can overload bracket operator.
I have no idea what's ContextString is, however, if ContextString is a Dictionary or the type uses brackets to get value, you can do it like this:
public string this[string strItemType]
{
get
{
try
{
return myContext.ContextString[strItemType];
}
catch (Exception ex)
{
return "";
}
}
set
{
try
{
myContext.ContextString[strItemType] = value;
}
catch (Exception ex) { }
}
}
I have many functions with different content but the parameters and try catch inside is almost similar. Is there anyway to wrap the function up so that can reduce redundant codes.
ResponseStatus GetPotatoList(GetPotatosRequest requestParam, out GetPotatosResponse response, out ResponseErrorType errorType)
{
ResponseStatus status = ResponseStatus.Fail;
response = new GetPotatosResponse();
//To Do
try
{
//To Do
status = ResponseStatus.Success;
}
catch(CustomException ex)
{
errorType = ResponseErrorType.CustomError;
}
catch(TimeoutException ex)
{
errorType = ResponseErrorType.Timeout;
}
catch(Exception ex)
{
errorType = ResponseErrorType.GeneralFailure;
}
return status;
}
You can pass an Action to your method.
ResponseStatus GetPotatoList(Action action1, Action action2, GetPotatosRequest requestParam, out GetPotatosResponse response, out ResponseErrorType errorType)
{
ResponseStatus status = ResponseStatus.Fail;
response = new GetPotatosResponse();
action1();
try
{
action2();
status = ResponseStatus.Success;
}
catch(CustomException ex)
{
errorType = ResponseErrorType.CustomError;
}
catch(TimeoutException ex)
{
errorType = ResponseErrorType.Timeout;
}
catch(Exception ex)
{
errorType = ResponseErrorType.GeneralFailure;
}
return status;
}
Then use it:
var response = GetPotatoList(
() => doSomething(),
() => doSomethingElse(),
requestParam,
out response,
out errorType);
I needed to provide functionality before and after invoking an original method whose signature didn't vary much.
I used Func<..>...
public static Func<string, string> Hello = name => "hello " + name;
public static string Hello2(string name) => wrap(Hello)(name);
// This does NOT retain the name of the arg for hints in the IDE
public static Func<string, string> Hello3 = name => wrap(Hello)(name);
private static Func<string, T> wrap<T>(Func<string, T> orig)
{
return name => orig(name.ToUpper());
}
Instead using Action you should maybe use a function that will take the request as the parameter and return your response object, then you can take benefit of generics to make the call and then handle specific cases. Also returning tuple or some generic type for the Result might be a good idea instead of using out parameters.
public static Tuple<TResponse, ResponseStatus, ResponseErrorType> GetResponse<TRequest, TResponse>(Func<TRequest, TResponse> action, TRequest request)
{
var status = ResponseStatus.Fail;
var errorType = ResponseErrorType.None;
var response = default(TResponse);
try
{
response = action(request);
status = ResponseStatus.Success;
}
catch (CustomException ex)
{
errorType = ResponseErrorType.CustomError;
}
catch (TimeoutException ex)
{
errorType = ResponseErrorType.Timeout;
}
catch (Exception ex)
{
errorType = ResponseErrorType.GeneralFailure;
}
return new Tuple<TResponse, ResponseStatus, ResponseErrorType>(response, status, errorType);
}
I am writing to seek help with regards to implementing a return statement for my test method. I am currently getting a null response from my test() method, but I would like to know, how can I catch the error from my "IsValidEmailDomain" method in my "test" method:
public static bool IsValidEmailDomain(MailAddress address)
{
if (address == null) return false;
var response = DnsClient.Default.Resolve(address.Host, RecordType.Mx);
try
{
if (response == null || response.AnswerRecords == null) return false;
}
catch (FormatException ex)
{
ex.ToString();
throw ex;
//return false;
}
return response.AnswerRecords.OfType<MxRecord>().Any();
}
public static bool IsValidEmailDomain(string address)
{
if (string.IsNullOrWhiteSpace(address)) return false;
MailAddress theAddress;
try
{
theAddress = new MailAddress(address);
}
catch (FormatException)
{
return false;
}
return IsValidEmailDomain(theAddress);
}
public static string test()
{
string mail = "########";
if (IsValidEmailDomain(mail))
{
return mail;
}
else
{
///How to return error from IsValidEmailDomain() method.
}
}
Any hint or suggestion would be most appreciated.
public static string test()
{
string mail = "########";
bool? answer;
Exception ex;
try
{
answer = IsValidEmailDomain(mail);
}
catch(Exception e)
{
ex = e;
}
if (answer)
{
return mail;
}
else
{
// here you can check to see if the answer is null or if you actually got an exception
}
}
There are a couple of ways to do this.
Use an out parameter.
Throw an exception if there was an issue. (Defeats the purpose of bool)
I usually go with a combination when I come across something like this.
public bool IsValidEmailDomain(string email)
{
return IsValidEmailDomain(email, false);
}
public bool IsValidEmailDomain(string email, bool throwErrorIfInvalid)
{
string invalidMessage;
var valid = ValidateEmailDomain(email, out invalidMessage);
if(valid)
return true;
if (throwErrorIfInvalid)
throw new Exception(invalidMessage);
return false;
}
public bool ValidateEmailDomain(string email, out string invalidMessage)
{
invalidMessage= null;
if (....) // Whatever your logic is.
return true;
invalidMessage= "Invalid due to ....";
return false;
}
I am trying to fully understand how I can simplify the following:
public ActionResult Create(string ds) {
InitializeServices(ds, "0000");
vm.Account = new Account {
PartitionKey = "0000",
RowKey = "0000",
Created = DateTime.Now,
CreatedBy = User.Identity.Name
};
}
catch (ServiceException ex) {
ModelState.Merge(ex.Errors);
}
catch (Exception e) {
Trace.Write(e);
ModelState.AddModelError("", "Database access error: " + e.Message);
}
return View("CreateEdit", vm);
}
I had a few great answers and the following was suggested:
private void HandleException(Action action) {
try {
action();
}
catch (ServiceException ex) {
ModelState.Merge(ex.Errors);
}
catch (Exception e)
{
Trace.Write(e);
ModelState.AddModelError("", "Database access error: " + e.Message);
}
}
RunAndHandleExceptions(new Action(() =>
{
//Do some computing }
));
This looks like a really great solution but I still don't understand how I can pass in my
parameters into the action. What I need to do is to pass in the following:
string ds
System.Web.Mvc.ModelState ModelState (passed as a reference)
Just
HandleException(() => someFunction(ds, ModeState));
should do it
To get the return value, you need a Func<>, not Action<>:
private TR HandleException<TR>(Func<TR> action)
{
try
{
return action();
}
catch (ServiceException ex)
{
ModelState.Merge(ex.Errors);
}
catch (Exception e)
{
Trace.Write(e);
ModelState.AddModelError("", "Database access error: " + e.Message);
}
return default(TR); // null for reference types
}
You then would use it, e.g. without an existing function:
bool result = HandleException(() =>
{
if (string.IsNullOrEmpty(ds))
return false;
// do interesting stuff that throws many kinds of exceptions :)
// Note: freely use ds and ModelState from surrounding scope,
// no need to 'pass them'
return true;
});
Have you looked at RedirectToAction?
return this.RedirectToAction(c => c.SomeAction(MyParam));
You can define an action with up to 16 parameters (no discussion, if that number is useful, please). So, sour call could look like:
private void HandleException(Action<string, System.Web.Mvc.ModelState ModelState > action) {
Edit
Here is an example with an action having parameter:
private void RunHandleException(Action<int> action)
{
action(someIntValue);
}
...
RunAndHandleExceptions((someInt) =>
{
//Do some computing
});
And here is an example with a function having a return value:
private void RunHandleException(Func<bool, int> action)
{
bool returnValue = action(someIntValue);
}
...
RunAndHandleExceptions((someInt) =>
{
//Do some computing
return true;
});