You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过API在SenseNet数据库保存自定义实体并创建对应模型?

我来帮你梳理下在SenseNet中创建自定义实体模型并保存数据的具体步骤,优先覆盖你想要的ASP.NET方案,再补充前端API的选项:

在SenseNet中创建自定义实体模型并保存数据(ASP.NET/前端API方案)

一、创建自定义实体模型(优先ASP.NET后端实现)

SenseNet的自定义内容类型(对应你的模型)可以通过代码类或者XML定义文件(CTD)来创建,推荐用代码类的方式在ASP.NET项目中实现,更贴合.NET生态:

1. 定义内容类型类

在你的ASP.NET项目中创建一个继承自GenericContent的类,标记内容类型名称并定义字段:

using SenseNet.ContentRepository;
using SenseNet.ContentRepository.Schema;

[ContentTypeName("PersonEntity")]
public class PersonEntity : GenericContent
{
    // 对应你的TypeScript实体中的name字段(复用SenseNet内置的DisplayName作为显示名称)
    [RepositoryProperty("DisplayName", RepositoryDataType.Text)]
    public string DisplayName
    {
        get => base.GetProperty<string>("DisplayName");
        set => base.SetProperty("DisplayName", value);
    }

    // 对应你的TypeScript实体中的email字段
    [RepositoryProperty("Email", RepositoryDataType.Text)]
    public string Email
    {
        get => base.GetProperty<string>("Email");
        set => base.SetProperty("Email", value);
    }

    // 后续添加图片字段的示例(Binary类型)
    //[RepositoryProperty("ProfileImage", RepositoryDataType.Binary)]
    //public BinaryData ProfileImage
    //{
    //    get => base.GetProperty<BinaryData>("ProfileImage");
    //    set => base.SetProperty("ProfileImage", value);
    //}

    // 必要的构造函数
    public PersonEntity(Node parent) : base(parent) { }
    public PersonEntity(NodeToken nt) : base(nt) { }
}

注意:SenseNet中每个节点都有一个唯一的Name属性(用于URL路径),这里我们复用内置的DisplayName存储你的name字段,节点的Name可以用邮箱或生成的唯一值设置(后面保存时会提到)。

2. 注册内容类型

在项目启动时(比如Startup.cs或Program.cs)注册这个内容类型,让SenseNet识别它:

// 在应用初始化阶段添加
ContentManager.RegisterContentType(typeof(PersonEntity));

备选:用CTD文件定义(XML方式)

如果你更习惯用XML配置,可以在SenseNet的ContentTypes文件夹下创建PersonEntity.ctd文件,内容如下:

<ContentType name="PersonEntity" parentType="GenericContent" handler="YourNamespace.PersonEntity, YourAssemblyName">
  <DisplayName>Person Entity</DisplayName>
  <Description>Custom person entity with name and email fields</Description>
  <Fields>
    <Field name="DisplayName" type="Text">
      <DisplayName>Name</DisplayName>
      <Configuration>
        <Required>true</Required>
      </Configuration>
    </Field>
    <Field name="Email" type="Text">
      <DisplayName>Email</DisplayName>
      <Configuration>
        <Required>true</Required>
        <RegexPattern>^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$</RegexPattern>
      </Configuration>
    </Field>
    <!-- 后续图片字段配置 -->
    <!--<Field name="ProfileImage" type="Binary">
      <DisplayName>Profile Image</DisplayName>
      <Configuration>
        <AllowedExtensions>.jpg,.jpeg,.png</AllowedExtensions>
      </Configuration>
    </Field>-->
  </Fields>
</ContentType>

二、前端API创建模型(不推荐,仅管理员可用)

如果必须通过前端API创建内容类型,需要使用SenseNet的OData Admin API,且调用者必须有管理员权限。发送POST请求到/odata.svc/ContentTypes,请求体如下:

{
  "__ContentType": "ContentType",
  "Name": "PersonEntity",
  "ParentPath": "/Root/ContentTypes/GenericContent",
  "DisplayName": "Person Entity",
  "Fields": [
    {
      "Name": "DisplayName",
      "Type": "Text",
      "Configuration": { "Required": true }
    },
    {
      "Name": "Email",
      "Type": "Text",
      "Configuration": { 
        "Required": true,
        "RegexPattern": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"
      }
    }
  ]
}

注意:这种方式风险较高,因为内容类型定义涉及数据结构,建议还是通过后端代码维护。

三、保存实体的POST请求配置

创建好模型后,你需要通过SenseNet的OData API来创建PersonEntity实例,具体配置如下:

1. API端点URL

POST请求的URL格式为:/odata.svc/[父节点路径]/CreateDocument

  • 比如你要把人员实体保存在/Root/People这个父文件夹下(需要先在SenseNet中创建这个文件夹),URL就是:/odata.svc/Root/People/CreateDocument

2. 请求头设置

  • Content-Type: application/json(仅当发送JSON数据时)
  • Authorization: Bearer {你的授权Token}(需要先通过SenseNet的认证接口获取Token)

3. Angular代码示例(保存基础字段)

结合你的TypeScript实体,创建一个服务来发送请求:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { PersonEntity } from './person-entity';

@Injectable({ providedIn: 'root' })
export class PersonService {
  private baseApiUrl = '/odata.svc/Root/People/CreateDocument';
  private authToken = 'your-auth-token-here'; // 替换为实际获取的Token

  constructor(private http: HttpClient) { }

  createPerson(person: PersonEntity) {
    // 构造SenseNet要求的请求体,注意节点Name必须唯一
    const requestBody = {
      "__ContentType": "PersonEntity",
      "Name": person.email.replace(/[@.]/g, '-'), // 用邮箱生成唯一节点名称
      "DisplayName": person.name, // 映射到你的name字段
      "Email": person.email
    };

    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      })
    };

    return this.http.post(this.baseApiUrl, requestBody, httpOptions);
  }
}

4. 后续添加图片字段的上传示例

当需要上传图片时,要改用multipart/form-data格式,用FormData来构造请求体:

createPersonWithImage(person: PersonEntity, imageFile: File) {
  const formData = new FormData();
  formData.append('__ContentType', 'PersonEntity');
  formData.append('Name', person.email.replace(/[@.]/g, '-'));
  formData.append('DisplayName', person.name);
  formData.append('Email', person.email);
  formData.append('ProfileImage', imageFile, imageFile.name);

  const httpOptions = {
    headers: new HttpHeaders({
      'Authorization': `Bearer ${this.authToken}`
      // 不要手动设置Content-Type,浏览器会自动添加正确的边界
    })
  };

  return this.http.post(this.baseApiUrl, formData, httpOptions);
}

内容的提问来源于stack exchange,提问作者Janneman96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:58:00