【问题标题】:Returning multiple values from WebApi (post) to AngularJs将多个值从 WebApi(post)返回到 AngularJs
【发布时间】:2018-08-14 13:46:46
【问题描述】:

我正在使用 .net core C#、WebApi 和 AngularJs。

为了保存数据,我的 Angularjs 代码对我的 WebApi 进行了 $http 调用。我可以很好地从我的 api 返回单个数据,但不确定在这里返回多个值的最佳方法是什么。我可以用逗号分隔然后返回,但想知道是否有更好的方法。

所以基本上当 API 将数据保存到我的数据库时,我想返回一个变量,如果保存成功则返回布尔值,如果保存不成功则返回异常消息。下面是我的代码。

AngularJs 代码:

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

WebApi 代码:

[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;
}

让我知道最好的方法。

【问题讨论】:

  • 为什么要返回truefalse?如果保存成功,返回someDataToReturn。另一个,返回带有抛出异常的 HTTP 错误代码。

标签: c# angularjs asp.net-web-api


【解决方案1】:

首先,您应该检查请求正文中的值是否正确填充。

看看DataAnnotations。 您可以使用注释来指定模型中哪些属性是必需的、最小和最大长度等。

这是一个关于如何定义 UserData 类所需的 Name 属性的示例

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

如果请求模型不满足在 UserData 类 DataAnnotations 上设置的指定规则,则上下文 ModelState 将设置为 false 并包含 DataAnnotations 错误。 这可用于确定当前请求是否为错误请求并从中返回正确的 http 状态代码。

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

然后关于 SaveData 方法。在控制器中捕获异常并从那里返回正确的状态码

[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);
    }                
}

【讨论】:

  • @Macus,谢谢这个作品。有一件事虽然我使用状态 Ok 可以正常工作,但没有任何 InternalServerError 返回代码,因为它给了我错误,这在当前上下文中不存在。这个有没有替代品。我正在使用 .net core 2.0 c#。 Status Ok、BadRequest 等是 Microsoft.AspNetCore.Mvc ControllerBase 类的一部分。可能是我错过了,但我在此类中找不到等效的 InternalServerError。
  • @aman 太棒了!以下是如何在核心stackoverflow.com/a/37793718中返回 500@
  • 知道了。最后一个问题。使用上面的 API,我可能会发送另一个参数,它基本上是一个布尔值 true 或 false。如果为真,则意味着用户没有在数据参数中发送任何用户数据,在这里我需要更新 db.xml 中的标志。现在上面的问题是,由于数据参数为空,model.isvalid 变为下降。我不认为这是一个好方法,但目前这是我可能需要处理的。有没有解决方法。我当然可以检查数据是否为空,然后执行 ModelStatis.IsValid 但它可能会破坏它的目的。
  • @aman 听起来您应该为该逻辑创建一个新的端点。如果该方法有多个职责,那么您很可能应该将其分解为多个部分
【解决方案2】:

您可以使用Controller 类方法Json(object data)。比如:

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

this

【讨论】:

    【解决方案3】:

    你可以创建一个实体并返回它

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

    或只有

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

    【讨论】:

      【解决方案4】:

      标准方式是:
      返回201状态码
      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();
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 1970-01-01
        • 2015-04-15
        相关资源
        最近更新 更多