Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i set return so it accepts class1 or class2?

Tags:

c#

class

how can i, in my function start to fill the parameters for the class it is supposed to return, but if an exception occurs i'll return my error class instead?

public **** function()
    {
        try
        {
            Articles articles = new Articles();
            articles.articleid = 234;
            articles.articlename = "Milk";
            articles.deleted = 0;

            //continue fill Articles 
            //and an exception occurs


            return articles;

        }
        catch (Exception e)
        {
            Errors Error = new Errors();
            Error.exceptionmessage = e.Message;
            Error.exceptionname = e.ToString();
            Error.httpcode = 500;


            return Error;
        }
    }

is this possible and a good thing to do? or should i just extend all return classes with my error class, even though i will return much info with allot of null values. i would like to send as little data as possible and if my function fails i'll just send back the error.

UPDATE

sorry for not giving enough inforamtion about my situation this is a function that i want to use in a webservice

[OperationContract]
    [WebGet(
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    **** Function();

so i dont think i can just throw an exception. i would like to return a class of articles if all is well so i dont have to convert my data to JSON but if something goes wrong i would like to send http code 500 Internal Server Error to the client. i have not yet read all answers but i think i'll have to include my error class in all my other return classes so the client can now when something went wrong?

like image 271
Dendei Avatar asked Nov 30 '22 20:11

Dendei


1 Answers

UPDATE:

That gives more insight on what you want to do. Since you can't throw exceptions, you should have a base result class. I usually do this for WCF methods I call through javascript, since it can't handle the exceptions nicely.

So you'll want a base class like:

[DataContract]
public class AjaxResult
{
    public static AjaxResult GetSuccessResult()
    {
        return new AjaxResult();
    }

    [DataMember]
    public int Status { get; set; }
    [DataMember]
    public string Error { get; set; }
}

Then you can inherit this, adding any data you would want to return. This example returns a single product object and a list of validation errors.

[DataContract]
public class SingleProductResult : AjaxResult
{
    [DataMember]
    public Product Data { get; set; }
    [DataMember]
    public IList<int> ValidationErrors { get; set; }
}

You can also opt to create a generic wrapper so you don't have to write to much code in your methods. I usually put this in a base class and let all WCF services inherit from that class.

protected T PerformAjaxOperation<T>(Func<T> action) where T : AjaxResult, new()
{
    try
    {
        return action();
    }
    catch (AccessDeniedException ade)
    {
        // -- user tried to perform an invalid action
        return new T()
        {
            Status = AjaxErrorCodes.AccessDenied,
            Error = ade.ToString()
        };
    }
    catch (Exception ex)
    {
        return new T()
        {
            Error = ex.ToString(),
            Status = 1
        };
    }
}

Then just use it like so:

public SingleProductResult GetProduct(int productId)
{
    return PerformAjaxOperation(() =>
    {
        return retval = new SingleProductResult()
            {
                Data = ProductServiceInstance.GetProduct(productId)
            };
    });
}
public AjaxResult DeleteProduct(int productId)
{
    return PerformAjaxOperation(() => {
        ProductServiceInstance.DeleteProduct(productId);
        return AjaxResult.GetSuccessResult();
    });
}

So, if everything proceeds smoothly, error will be 0 and message will be null. If an exception is thrown, then it will be caught by the PerformAjaxOperation() function and stuffed inside the AjaxResult object (or a derivative of it) and return to the client.


Previous answer:

I don't think this is a good idea. What you can do is create a custom exception by creating a class that inherits from Exception and add properties there that you want to save. Then when an exception occurs, you just catch it and stuff it inside this new exception along with other details. Then throw this exception instead. You can then catch this exception in the higher levels and display the proper message.

an example:

public IList<Articles> GetArticles()
{
    try
    {
        return GetSomeArticlesFromDatabase();
    }
    catch (Exception innerException)
    {
        throw new MyCustomException("some data", 500, innerException);
    }
}
public class MyCustomException : Exception
{
    public int HttpCode { get; set; }
    public MyCustomException(string errorMessage, int httpCode, Exception innerException)
        : base(errorMessage, innerException) {
            HttpCode = httpCode;
    }
}
public void EntryPoint()
{
    try
    {
        DoSomething();
        var result = GetArticles();
        DoSomething();
        DisplayResult(result);
    }
    catch (MyCustomException ex)
    {
        ReturnHttpError(ex.Message, ex.HttpCode);
    }
}
like image 62
Mel Avatar answered Dec 06 '22 07:12

Mel