david
david

Reputation: 87

Passing a message back with response code via class

I am using a web api but I want to be able to pass back a message with my response but I am using this method outside in a class how would one do that in the example of the following.

public HttpStatusCode CreateInvoice(string PumpName,string customerCode, double fuelQty, double price)
{
        HttpStatusCode retval = new HttpStatusCode();
        SAPbobsCOM.Documents oInvoice = company.GetBusinessObject(BoObjectTypes.oInvoices);

            oInvoice.DocDate = DateTime.Now;
            oInvoice.CardCode = customerCode;
            oInvoice.Lines.ItemCode = "DSL";
            oInvoice.Lines.Quantity = fuelQty;
            oInvoice.Lines.LineTotal = price;
            oInvoice.Lines.Add();               


            int addInvoice = oInvoice.Add();
            if (addInvoice == 0)
            {
                retval = HttpStatusCode.OK;
            }
            if (addInvoice < 0)
            {
                string errorDescription = company.GetLastErrorDescription();        
                retval = HttpStatusCode.NotModified;
            }

            return retval;           
    }

I want to be able to pass back this line as part of the response message I no how to do it in the controller but this function is outside in a class. As there I dont have access to the request object?

string errorDescription = company.GetLastErrorDescription();        

Edit 2 Ok so I created the function with httprequest message but i am not seeing the result in the header its showing me status 200 ok for invoice created but not the message.

public HttpResponseMessage CreateInvoice(string PumpName,string customerCode, double fuelQty, double price,string FuelType)
{
        HttpResponseMessage retval = new HttpResponseMessage();



        SAPbobsCOM.Documents oInvoice = company.GetBusinessObject(BoObjectTypes.oInvoices);
        HttpRequestMessage Errordescription = new HttpRequestMessage() ;

            oInvoice.DocDate = DateTime.Now;
            oInvoice.CardCode = customerCode;
            oInvoice.Lines.ItemCode = FuelType;
            oInvoice.Lines.Quantity = fuelQty;
            oInvoice.Lines.LineTotal = price;
            oInvoice.Lines.Add();              


            int addInvoice = oInvoice.Add();

            if (addInvoice == 0)
            {
                retval.StatusCode = HttpStatusCode.OK;
                retval.RequestMessage=new HttpRequestMessage(HttpMethod.Post, "Invoice has been created!");

            }
            if (addInvoice < 0)
            {

                retval.StatusCode = HttpStatusCode.NotAcceptable;
                retval.RequestMessage = new HttpRequestMessage(HttpMethod.Post,string.Format("Invoice was not created {0} sap code error {1}!", company.GetLastErrorDescription(),addInvoice));
                            }

            HttpResponseMessage response = retval;
            return response;
}

Here is how I consume the message in my API Controller.

public HttpResponseMessage Post(string PumpName, string FuelTagNumber,
     double FuelQty, double FuelValue, string FuelType, string TransactionDate, string TransActionDate, string systemgroup1, string systemgroup2, string systemgroup3, string systemgroup4)
{
        HttpResponseMessage retVal = new HttpResponseMessage();

        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");

        int connect = _boneAPi.Connect();
            if (connect == 0)

            {
                string CustomerCode = _boneAPi.GetCustomerCodeByVechicleTag(FuelTagNumber);

                HttpResponseMessage _invoiceStatusCode = _boneAPi.CreateInvoice(PumpName, CustomerCode, FuelQty, FuelValue,FuelType);
            retVal = _invoiceStatusCode;

                    _boneAPi.ImportTransactionToTable("", CustomerCode, TransactionDate, TransactionDate, systemgroup1, systemgroup3, FuelTagNumber, systemgroup2, systemgroup4, FuelQty.ToString(), FuelValue.ToString(), FuelType, "1");                       
   }

            return retVal;

 }

To show post man result

enter image description here

Edit 2

To Show others how I solved it.

 public HttpResponseMessage CreateInvoice(string PumpName, string customerCode, double fuelQty, double price, string FuelType)
 {
    HttpResponseMessage retval = new HttpResponseMessage();
    SAPbobsCOM.Documents oInvoice = company.GetBusinessObject(BoObjectTypes.oInvoices);
    HttpRequestMessage Errordescription = new HttpRequestMessage();

    oInvoice.DocDate = DateTime.Now;
    oInvoice.CardCode = customerCode;
    oInvoice.Lines.ItemCode = FuelType;
    oInvoice.Lines.Quantity = fuelQty;
    oInvoice.Lines.LineTotal = price;
    oInvoice.Lines.Add();

    int addInvoice = oInvoice.Add();
    if (addInvoice == 0)
    {
       retval.StatusCode = HttpStatusCode.OK;
       retval.RequestMessage = new HttpRequestMessage(HttpMethod.Post, "");
       retval.Content = new StringContent("Invoice has been created!");
    }
    if (addInvoice < 0)
    {
       retval.StatusCode = HttpStatusCode.NotAcceptable;
       retval.Content = new StringContent(string.Format("Invoice was not created {0} sap code error {1}!", company.GetLastErrorDescription(), addInvoice));
     }
    HttpResponseMessage response = retval;
    return response;
}

Upvotes: 0

Views: 652

Answers (2)

Dylan Nicholson
Dylan Nicholson

Reputation: 1368

I'd strongly recommend that a function that is creating invoices shouldn't know/care about http status codes at all. All you need to know is whether it created a new invoice or not, and if not, why not. One option is to use an exception, but if "not modified, for reason xxx" is something you expect to happen reasonably often then that's probably not the best way forward. What you arguably want is some sort of discriminated union, but C# doesn't have a nice built in way of achieving that, so you could define a "response" type that can hold either a successful response or an error description. Then in your controller layer (that does need to know about http status codes etc), determine what sort of response to return to the client based on the contents of the response object. If you'd like the response object itself to be responsible for determining whether the error message should be exposed, ít could have a method that takes two lambdas, calling either one if in 'success' state, or the other (with the error description as a parameter) in the failed state. But that's arguably overkill.

Upvotes: 2

PhilS
PhilS

Reputation: 624

How about making the return a Tuple

If you are using c# 7 it would look like this:

public (HttpStatusCode code, string description) CreateInvoice(string PumpName, string customerCode, double fuelQty, double price)
{
    HttpStatusCode retval = new HttpStatusCode();
    string errorDescription = string.Empty;

    SAPbobsCOM.Documents oInvoice = company.GetBusinessObject(BoObjectTypes.oInvoices);

    oInvoice.DocDate = DateTime.Now;
    oInvoice.CardCode = customerCode;
    oInvoice.Lines.ItemCode = "DSL";
    oInvoice.Lines.Quantity = fuelQty;
    oInvoice.Lines.LineTotal = price;
    oInvoice.Lines.Add();


    int addInvoice = oInvoice.Add();
    if (addInvoice == 0)
    {
        retval = HttpStatusCode.OK;
    }
    if (addInvoice < 0)
    {
        errorDescription = company.GetLastErrorDescription();
        retval = HttpStatusCode.NotModified;
    }

    return (code: retval, description: errorDescription);
}

If an older version you would need to return a Tuple<HttpStatusCode, string>

Upvotes: 3

Related Questions