【问题标题】:Angular how to use $save with WebAPIAngular 如何在 WebAPI 中使用 $save
【发布时间】:2015-08-29 03:06:20
【问题描述】:

我有一个资源服务,代码如下

function productResource($resource) {    
return $resource("http://localhost/api/product/:id", null,
{
   'update':{method:'PUT'}
});

我设置了一条路线来编辑这样的产品

  .state("productEdit", 
  {
   abstract: true,
   url: "/products/edit/:id",
   templateUrl: "app/products/productEditView.html",
   controller: "productEditCtrl as vm",
   resolve: {
      productResource: "productResource",
      product: function (productResource, $stateParams) {
        var id = $stateParams.id;
        return productResource.get({id: id}).$promise;
    }
}
})

我的控制器是这样的

    function productEditCtrl(product,  productResource, $state) {
    var vm = this;
    vm.product=  product;
    if (vm.product.data && vm.product.data.id) {
        vm.title = "Edit: " + vm.product.data.cusip;
    }
    else {
        vm.title = "New product"
    }
    vm.submit = function(){
    vm.product.$save(
            function (data) {
                toastr.success("Save Successful");
            }
        );
    };

Web API 返回一个具有以下结构的动态对象

public class ResponseResult {
public dynamic Data { get; set; }
public HttpStatusCode StatusCode { get; set; }
public bool DataIsValid
}

webAPI 控制器操作如下所示

[Route("api/product/{productId}")]
[HttpGet]
public dynamic FindproductById(Guid productId)
{            
     productDto productDto = this.productManager.FindproductById(productId);
     return new ResponseResult(productDto, HttpStatusCode.OK, productDto.ValidationResults, null);
}

[Route("api/product")]
[HttpPost]
public dynamic Createproduct(productDto productDto)
{

   Verify.IsNotNull("product dto", productDto);

   if (productDto.Id == Guid.Empty)
   {
     this.productManager.Createproduct(productDto);
   }

   return new ResponseResult(productDto, HttpStatusCode.OK,    productDto.ValidationResults, null);
}

我的问题是当我调用 $save 函数时,它会返回空产品数据,因为 $save 与 ResponseResult 绑定,我需要将产品数据发送回 webapi。我不知何故需要将从 webapi 返回的产品数据绑定到 vm.product,所以当我调用 vm.product.$save 时,它​​可以工作。我该怎么做?

【问题讨论】:

  • web api 产品控制器/动作看起来如何?
  • 马丁,我在问题中添加了控制器代码
  • 您是否为 ResponseResult 创建了一个空的构造函数?过去我遇到过缺少创建空构造函数的问题。
  • Simcha,空的构造函数没有任何区别。问题不在于 web api,而在于 $resource 是如何工作的。如果将 Web api 中 GET 的返回类型更改为 ProductDto 而不是 ResponseResult,则整个代码都可以正常工作。
  • 为什么你的返回类型是dynamic而不是IHttpActionResult,如果你想返回一些内容或者只是做一个return Ok(),你可以使用return Created<T>(string location, T content)

标签: angularjs asp.net-web-api


【解决方案1】:

在使用$resource 解析状态时,我正在使用以下设置。

我有一个CustomerService,它被注入到解析中:

angular
    .module("app.customer")
    .factory("CustomerService", CustomerService);

function CustomerService($resource) {
    return $resource("/api/customers/:id", { id: "@customerId" })
}

我的路线配置如下所示:

.state("customers.details", {
    url: "/{id}/",
    templateUrl: "/app/customers/customers.details.html",
    controller: "CustomersController",
    controllerAs: "vm",
    resolve: {
        customer: function (CustomerService, $stateParams) {
            return CustomerService.get({ id: $stateParams.id });
        }
    }
})

customer 被注入到CustomersController 中,它允许我在customer 上同时执行.$save.$update

您的 Web api 控制器可能如下所示:

[Route("")]
public async Task<IHttpActionResult> Post(CustomerCreateCommand model)
{
    var customer = await customerRepository.InsertAsync(model);

    return Created<CustomerViewModel>("/api/customers/" + customer.Id, MapToViewModel<CustomerViewModel>(customer));
}

在这种情况下,如果您无法控制 API,并且它没有返回预期的实体,$resource 将无法开箱即用。

您面临的问题是您获得的实体类型与您希望发送回 API 的实体类型不同。您需要解开 data 字段,因为这是 API 在执行 POST 时所期望的。

您可以像下面这样编写提交函数,在其中使用来自 vm.product.data 的值创建一个新资源,该资源应映射到服务器 productDto 类:

vm.submit = function() {
  new productResource(vm.product.data).$save(function () {  
    // saved successfully
  });
};

【讨论】:

  • 马丁,感谢您的建议。但不幸的是,我不控制 API,因此无法更改它。
猜你喜欢
  • 2019-07-02
  • 2019-03-29
  • 2017-11-02
  • 2019-08-09
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
相关资源
最近更新 更多