0

I am using .net core C#, WebApi & AngularJs.

For saving data my Angularjs code makes a $http call to my WebApi. I can return single data from my api fine but not sure whats the best method to return multiple values here. I can make it comma separated and then return as well, but wanted to know if there is a better approach to this.

So basically when the API saves data to my db, I want to return a variable, boolean value if the save was successful and an exception message in case the save was not successfully. Below is my code.

AngularJs Code:

service.saveData(data).then(function (res) {                          
    //get someDataToReturn, dataSaved & exception raised if any from db save here.
    }, function (err) {
});

WebApi Code:

[HttpPost("data/save")]
public async Task<IActionResult> SaveData([FromBody] List<UserData> data)
{
    bool dataSaved = true;
    string someDataToReturn = string.Empty;
    //do some processing and updating someDataToReturn here         

    //Saving data to DB
    dataSaved = SaveData(data);                

    //I want to return someDataToReturn, dataSaved(true or false) and exception raised from SaveData if any 
    return Ok(someDataToReturn);
}

//DB Call to save data
public bool SaveData(List<UserData> data)
{           
    try
    {
        foreach (var set in data)
        {
            //creating query etc

            _db.Execute(query);
        }                

        return true;
    }
    catch (SqlException ex)
    {

    }
    return false;
}

Let me know the best approach for this.

1
  • Why you should to return true or false? If the saving successed, return someDataToReturn. Another, return HTTP error code with the throwed exception. Commented Aug 14, 2018 at 13:53

4 Answers 4

1

First of, you should check if the values in your request body is correctly populated.

Take a look at DataAnnotations. You can use annotations to specify which properties in your model that are Required, Min and Maxlength etc.

Here's an example on how to define a Name property to be required on the UserData class

public class UserData
{
    [Required]  
    public string Name { get; set; }        
}

If the request model do not fulfill the specified rules set on the UserData class DataAnnotations, the context ModelState will be set to false and contain the DataAnnotations errors. This can be used to determind if the current request is a bad request and return a proper http status code from that.

[HttpPost("data/save")]
public async Task<IActionResult> SaveData([FromBody] List<UserData> data)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState); //will return a 400 code
    ...

Then regarding the SaveData method. Capture the exception in the controller and return a proper status code from there

[HttpPost("data/save")]
public async Task<IActionResult> SaveData([FromBody] List<UserData> data)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState); //400 status code

    try
    {
        SaveData(data);
    }
    catch(Exception e)
    {
        return InternalServerError(e); //500 status code
    }

    string someDataToReturn = string.Empty;
    return Ok(someDataToReturn ); //200 status code
}

public void SaveData(List<UserData> data)
{           
    foreach (var set in data)
    {
        //creating query etc

       _db.Execute(query);
    }                
}
Sign up to request clarification or add additional context in comments.

4 Comments

@Macus, Thanks this works. One thing though I am using status Ok which works fine but there is nothing as InternalServerError return code as it gives me error that this does not exists in current context. Is there an replacement for this. I am using .net core 2.0 c#. Status Ok, BadRequest etc are a part of Microsoft.AspNetCore.Mvc ControllerBase class. May be I missed but I could not find equivalent of InternalServerError in this class.
@aman great! Here’s how to return 500 in core stackoverflow.com/a/37793718
Got it. One last question though. With the above API I might be sending another parameter which is basically a boolean value true or false. If true that means user is not sending any userdata in the data param and here I need to update a flag in db. Now issue with the above is, since data param is null the model.isvalid becomes fall. I dont think this a good approach but currently this is what I might need to handle. Is there a workaround this. I can ofcourse check for data is null or not and then do ModelStatis.IsValid but it might defeat the very purpose of it.
@aman it sounds more like you should create a new enpoint for that logic. If the method has more than one responsibility then u most likely should break it into pieces
0

You can use the Controller class method Json(object data). Something like:

[HttpPost("data/save")]
public async Task<IActionResult> SaveData([FromBody] List<UserData> data)
{
    return this.Json(SaveData(data));
}

See this.

Comments

0

you can create an entity and return it

public class BaseResult{
     public bool Result{get;set;}
     public string Errors{get;set;}
}

or only

return Ok( new { result = dataSaved , error= exception.Message});

Comments

0

the standard way is:
return 201 status code
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201

    [HttpPost("data/save")]
    public async Task<IHttpActionResult> SaveData([FromBody] List<UserData> data)
    {
        try
        {
            if (!ModelState.IsValid)
                return BadRequest(ModelState); 

            // return response of 201 if you created the resource successfully
            // typically return this with a uri to the new resource
            return Created("location", saveData(data));
        }
        catch (Exception)
        {
            return InternalServerError();
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.