ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 错误:无法将PATCH应用于导航属性.那我该怎么办?

2019-06-24 09:52:48  阅读:219  来源: 互联网

标签:c odata asp-net-web-api2


我有一个Web API 2.2 OData 4服务使用实体框架的以下模型:

public class Company
{
  public int Id { get; set; }
  public string Name { get; set; }
  public virtual ICollection<CompanyType> CompanyTypes { get; set; }
}

public class CompanyType
{
  public int Id { get; set; }
  public string Name { get; set; }
  public virtual ICollection<Company> Companies { get; set; }
}

还有一点流畅的映射:

modelBuilder.Entity<Company>().HasMany(x => x.CompanyTypes).WithMany(x => x.Companies).Map(x =>
{
  x.MapLeftKey("CompanyId");
  x.MapRightKey("CompanyTypeId");
  x.ToTable("CompaniesCompanyTypes");
});

在我的CompanysController上,我有一个补丁方法,希望能够发送以下请求并成功更新公司名称并为该公司创建几个公司类型记录:

PATCH http://localhost:50113/MessagingService/odata//CompanyDTOs(1)/ HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-16
Host: localhost:50113
Content-Length: 174

{"Name":"Cheesy Peas Ltd","CompanyTypes":[{"Id":1,"Name":"Parent"},{"Id":2,"Name":"Subsidiary"}]}

但是我收到了:

{
  "error":{
    "code":"","message":"The request is invalid.","innererror":{
      "message":"delta : Cannot apply PATCH to navigation property 'CompanyTypes' on entity type 'Core.Models.Company'.\r\n","type":"","stacktrace":""
    }
  }
}

我认为我对PATCH请求的要求太高了,但是有没有人建议我应该如何实现这个目标呢?越简单越好 – 我不热衷于为我的客户端应用程序添加复杂性,如果我可以避免它并且更愿意使用PATCH而不是PUT.

非常感谢.如果您对此问题感兴趣并需要更多详细信息,请询问.

编辑

具体来说,我所追求的是在更新该关系的一部分中的记录时,能够在多对多表中插入记录.例如.如果学生有很多课程且课程有很多学生,那么当我更新学生A时,我可能还想添加对第一课的引用,删除对第二课的引用并保留对第三类的引用.

我在这里读完了OData文档:

http://docs.oasis-open.org/odata/odata-atom-format/v4.0/cs02/odata-atom-format-v4.0-cs02.html#_Toc372792732

但这对我来说有点神秘.我确信必须有一种方法可以使用“@ odata.bind”之类的东西.

有什么意见吗?

解决方法:

基于this workitem,您需要创建一组基本类型而不是列表复杂类型.

实体

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<ProductType> ProductTypes { get; set; }
}
public class ProductDto : Product
{
    public ICollection<int> ProductTypeIds { get; set; }
    public ICollection<string> ProductTypeNames { get; set; }
}
public class ProductType
{
    public int Id { get; set; }
    public string Name { get; set; }
}

行动

// PATCH odata/Products(5)
[AcceptVerbs("PATCH", "MERGE")]
public IHttpActionResult Patch([FromODataUri] int key, Delta<ProductDto> patch)
{
    object productTypeIds;
    patch.TryGetPropertyValue("ProductTypeIds", out productTypeIds);
    object productTypeNames;
    patch.TryGetPropertyValue("ProductTypeNames", out productTypeNames);

    // TODO: Implement update to database.

    return Updated(new ProductDto()); // for demo purpose
}

配置

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
builder.EntitySet<ProductDto>("ProductDtos");
builder.EntitySet<ProductType>("ProductType");
config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

提琴手

PATCH http://localhost:59829/odata/Products(1) HTTP/1.1

User-Agent: Fiddler
Host: localhost:59829
Content-Length: 83
Content-Type: application/json

{"Id":1, "Name":"A", "ProductTypeIds":[1,2], "ProductTypeNames":["AA", "BB"] }

结果

希望有所帮助.

标签:c,odata,asp-net-web-api2
来源: https://codeday.me/bug/20190624/1277359.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有