简体   繁体   English

Angular 8 post formData到ASP.NET Core API无法绑定IEnumerable / List

[英]Angular 8 post formData to ASP.NET Core API cannot bind IEnumerable/List

As title says 如标题所说

TypeScript model TypeScript模型

export interface RigheOrdiniBuoniSpesaData {
  id: number;
  id_ordine: number;
  id_taglio_buono_spesa: number;
  quantita: number;
}

which is part of another bigger object: 这是另一个更大对象的一部分:

export class OrdiniBuoniSpesaData {
  id: number;
  // OTHER FIELD
  // OTHER FIELD
  // OTHER FIELD
  righe_ordine: RigheOrdiniBuoniSpesaTableData;
}

Save method 保存方式

saveOrder(model: OrdiniBuoniSpesaData) {
    const headerPost: HttpHeaders = new HttpHeaders();
    headerPost.set('Content-type', 'application/x-www-form-urlencoded');
    const formData: FormData = new FormData();
    formData.append('id_cliente', model.id_cliente.toString());
    // VARIOUS FORM FIELDS
    //THIS IS ARRAY DATA
    formData.append('righe_ordine', JSON.stringify(model.righe_ordine));
    return this.http
        .post<boolean>(
          requestURL,
          formData,
          { headers: headerPost }
        )
        .pipe(
          catchError(this.handleError)
        );
}

Order json (valid Json) is visible in Chrome request capture clearly along with all data: 订单json(有效的Json)在Chrome请求捕获中与所有数据一起清晰可见:

[{"id":0,"id_ordine":0,"id_taglio_buono_spesa":1,"quantita":1},{"id":0,"id_ordine":0,"id_taglio_buono_spesa":1,"quantita":1},{"id":0,"id_ordine":0,"id_taglio_buono_spesa":1,"quantita":1},{"id":0,"id_ordine":0,"id_taglio_buono_spesa":3,"quantita":14}]

On API Side 在API方面

Receiving model for JSON JSON的接收模型

public class RigheOrdiniBuoniSpesaViewModel
{
    public long id { get; set; }
    public long id_ordine { get; set; }
    public long id_taglio_buono_spesa { get; set; }
    public int quantita { get; set; }
}

Which is in 哪个在

public class OrdiniBuoniSpesaViewModel 
    {
        public long id { get; set; }
        //OTHER VARIOUS FIELDS
        //I TRIED ALSO WITH LIST INSTEAD OF IENUMERABLE
        public IEnumerable<RigheOrdiniBuoniSpesaViewModel> righe_ordine {get;set;}
    }

(I TRIED ALSO WITH LIST INSTEAD OF IENUMERABLE, STILL NO LUCK!) (我也尝试过用列表代替无数的方式,仍然没有运气!)

Api controller signature: api控制器签名:

[HttpPost]
public async Task<IActionResult> PostSaveOrder([FromForm] OrdiniBuoniSpesaViewModel model) 
{.....code}

All the fields are binded correctly except for the righe_ordine array! 除righe_ordine数组外,所有字段均已正确绑定! I can see every field correctly but the array has count = 0. 我可以正确看到每个字段,但是数组的计数为0。

Strangely enough, if I examine the asp net request object (this.Request.Form) in the QuickWatch debug in visual studio: 足够奇怪的是,如果我在Visual Studio中的QuickWatch调试中检查了ASP网络请求对象(this.Request.Form):

this.Request.Form["righe_ordine"]
{[{"id":0,"id_ordine":0,"id_taglio_buono_spesa":1,"quantita":1},
{"id":0,"id_ordine":0,"id_taglio_buono_spesa":1,"quantita":1},
{"id":0,"id_ordine":0,"id_taglio_buono_spesa":1,"quantita":1},
{"id":0,"id_ordine":0,"id_taglio_buono_spesa":3,"quantita":14}]}    

Microsoft.Extensions.Primitives.StringValues

is present and correctly populated..... but for some reason binding it to the OrdiniBuoniSpesaViewModel fails.... 存在并正确填充.....但是由于某种原因将其绑定到OrdiniBuoniSpesaViewModel失败。

What am I doing wrong? 我究竟做错了什么? Any idea? 任何想法?

EDIT: 编辑:

For the moment the only solution I found is to directly catch the value just after entering the controller: 目前,我发现的唯一解决方案是在进入控制器后直接捕获该值:

string righeJson = this.Request.Form["righe_ordine"].ToString();
if(!string.IsNullOrEmpty(righeJson))
      model.righe_ordine = JsonConvert.DeserializeObject<IEnumerable<RigheOrdiniBuoniSpesaViewModel>>(righeJson);

I think you need to change your model name like this 我认为您需要像这样更改型号名称

In your js code 在你的js代码中

formData.append('righeOrdine', JSON.stringify(model.righe_ordine));

and c# 和C#

public class OrdiniBuoniSpesaViewModel 
    {
        public long id { get; set; }
        //OTHER VARIOUS FIELDS
        //I TRIED ALSO WITH LIST INSTEAD OF IENUMERABLE
        public IEnumerable<RigheOrdiniBuoniSpesaViewModel> RigheOrdine {get;set;}
    }

Update: Just for enhancement 更新:只是为了增强

Maybe you need to parse it before using it in your controller 也许您需要先解析它,然后才能在控制器中使用它

You can read my full code here 你可以在这里阅读我的完整代码

We will need to create interface and class to implement it. 我们将需要创建接口和类来实现它。

public interface IJsonParseService<T> where T : class
{
     T ToObject(string json);
}

public class JsonParseService<T> : IJsonParseService<T> where T : class
{
    public T ToObject(string json)
    {
      return JObject.Parse(json).Root.ToObject<T>();
    }
}

Then register it 然后注册

services.AddScoped(typeof(IJsonParseService<>), typeof(JsonParseService<>));

So your code should be something like this 所以你的代码应该是这样的

private readonly IJsonParseService<RigheOrdiniBuoniSpesaViewModel> _jsonParsePostOptionDefaultVm;

jsonParsePostOptionDefaultVm.ToObject(viewModel.RigheOrdiniBuoniSpesaViewModel); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM