0

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;
}
david
  • 87
  • 1
  • 9
  • 1
    Create `out string errorDescription` argument. – SᴇM Oct 25 '18 at 08:19
  • I want to also pass the error code as well so not just the description – david Oct 25 '18 at 08:21
  • 1
    Isn't that what SeM is suggesting? See the [out parameter modifier](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier). That said, a result class might be better. – ProgrammingLlama Oct 25 '18 at 08:21
  • 3
    Possible duplicate of [How can I return multiple values from a function in C#?](https://stackoverflow.com/questions/748062/how-can-i-return-multiple-values-from-a-function-in-c) – SᴇM Oct 25 '18 at 08:25
  • @SeM many thanks and yes +1 for the duplicate i was looking more httpresponse message but this works just as good. – david Oct 25 '18 at 08:29
  • 1
    You're welcome. If this is your api's controller method, you can return `HttpResponseMessage`, take a look at this: **[Action Results in Web API 2](https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results)**. – SᴇM Oct 25 '18 at 08:33
  • @SeM please see edit 2 I have tried with httpresonsemessage but im not seeinng the description in the post man. – david Oct 25 '18 at 09:11
  • @SeM the issue here was I was using message when should have been content. – david Oct 25 '18 at 09:34
  • 1
    @david So no everything is ok, or you've got other issues? – SᴇM Oct 25 '18 at 09:37
  • @SeM see edit 2 sem i solved it thank you for pointer to httpresponsemessage though is not accetale correct if the invoice has not been created. – david Oct 25 '18 at 09:38
  • Why just not return `retval`? You don't need to create another object. – SᴇM Oct 25 '18 at 10:05

2 Answers2

3

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>

PhilS
  • 624
  • 3
  • 5
2

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.

Dylan Nicholson
  • 1,301
  • 9
  • 23
  • This is an api function its passing back to the controller being wraped up in a libary and that is what I am retruning if its been created or not. – david Oct 25 '18 at 08:57
  • You said yourself this function wasn't in the controller. I assume you're able to change the code in the controller though? – Dylan Nicholson Oct 25 '18 at 08:59