范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

ASP。NETCore中的模型绑定

  什么是模型绑定
  控制器 Razor 和页面处理来自 HTTP 请求的数据。 例如,路由数据可以提供一个记录键,而发布的表单域可以为模型的属性提供一个值。 编写代码以检索这些值,并将其从字符串转换为 .NET 类型不仅繁琐,而且还容易出错。 模型绑定后会自动化该过程。 模型绑定系统: 从各种源(如路由数据、表单域和查询字符串)中检索数据。 在方法参数和公共 Razor 属性中向控制器和页面提供数据。 将字符串数据转换为 .NET 类型。 更新复杂类型的属性。 示例
  假设有以下操作方法: [HttpGet("{id}")] public ActionResult GetById(int id, bool dogsOnly)
  并且应用收到一个带有以下消息 URL 的请求: http://contoso.com/api/pets/2?DogsOnly=true
  在路由系统选择该操作方法之后,模型绑定执行以下步骤: 查找 GetById 的第一个参数,该参数是一个名为 id 的整数。 查找 HTTP 请求中的可用源,并在路由数据中查找 id ="2"。 将字符串"2"转换为整数 2。 查找 GetById 地下一个参数,该参数是一个名为 dogsOnly 的布尔值。 查找源,并在查询字符串中查找"DogsOnly=true"。 名称匹配不区分大小写。 将字符串"true"转换为布尔值 true。
  然后,该框架会调用 GetById 方法,为 id 参数传入 2,并为 dogsOnly 参数传入 true。
  在前面的示例中,模型绑定目标是简单类型的方法参数。 目标也可以是复杂类型的属性。 成功绑定每个属性后,将对属性进行模型验证。 有关绑定到模型的数据以及任意绑定或验证错误的记录都存储在 ControllerBase.ModelState 或 PageModel.ModelState 中。 为查明该过程是否已成功,应用会检查 ModelState.IsValid 标志。 目标
  模型绑定尝试查找以下类型目标的值: 将请求路由到的控制器操作方法的参数。 请求 Razor 路由到的 Pages 处理程序方法的参数。 控制器或 PageModel 类的公共属性(若由特性指定)。 [BindProperty] 属性
  可应用于控制器或 PageModel 类的公共属性,从而使模型绑定以该属性为目标:
  public class EditModel : InstructorsPageModel {     [BindProperty]     public Instructor Instructor { get; set; } [BindProperties] 属性
  可在 ASP.NET Core 2.1 及更高版本中获得。 可应用于控制器或 PageModel 类,以使模型绑定以该类的所有公共属性为目标:
  [BindProperties(SupportsGet = true)] public class CreateModel : InstructorsPageModel {     public Instructor Instructor { get; set; } HTTP GET 请求的模型绑定
  默认情况下,不绑定 HTTP GET 请求的属性。 通常,GET 请求只需一个记录 ID 参数。 记录 ID 用于查找数据库中的数据。 因此,无需绑定包含模型实例的属性。 只需要将属性绑定到 GET 请求中的数据的情况下,请将 SupportsGet 属性设置为 true:
  [BindProperty(Name = "ai_user", SupportsGet = true)] public string ApplicationInsightsCookie { get; set; } 源
  默认情况下,模型绑定以键值对的形式出现 HTTP 请求从以下源中获取数据: 表单域 请求正文(对于具有 [ApiController] 属性的控制器。) 路由数据 查询字符串参数 上传的文件
  对于每个目标参数或属性,按照之前列表中指示的顺序扫描清楚。 有几个例外情况: 路由数据和查询字符串值仅用于简单类型。 上传的文件仅绑定到实现 IFormFile 或 IEnumerable 的目标类型。
  如果默认源不正确,请使用下列属性之一来指定源: [FromQuery] - 从查询字符串获取值。 [FromRoute] - 从路由数据获取值。 [FromForm] - 从发布的表单字段中获取值。 [FromBody] - 从请求正文获取值。 [FromHeader] - 从 HTTP 标头获取值。
  这些属性: 分别添加到模型属性(而不是模型类),如以下示例所示: public class Instructor {  public int ID { get; set; }  [FromQuery(Name = "Note")]  public string NoteFromQueryString { get; set; } }
  选择性地在构造函数中接受模型名称值。 提供此选项的目的是应对属性名称与请求中的值不匹配的情况。 例如,请求中的值可能是名称中带有连字符的标头,如以下示例所示: public void OnGet([FromHeader(Name = "Accept-Language")] string language)[FromBody] 属性
  将 [FromBody] 特性应用于一个参数,以便从一个 HTTP 请求的正文填充其属性。 ASP.NET Core 运行时将读取正文的责任委托给输入格式化程序。 输入格式化程序的解释位于本文后面部分。
  将 [FromBody] 应用于复杂类型参数时,应用于其属性的任何绑定源属性都将被忽略。 例如,以下 Create 操作指定从正文填充其 pet 参数:
  public ActionResult Create([FromBody] Pet pet)
  Pet 类指定从查询字符串参数填充其 Breed 属性:
  public class Pet {     public string Name { get; set; }      [FromQuery] // Attribute is ignored.     public string Breed { get; set; } }
  在上面的示例中: [FromQuery] 特性被忽略。 Breed 属性未从查询字符串参数进行填充。
  输入格式化程序只读取正文,不了解绑定源特性。 如果在正文中找到合适的值,则使用该值填充 Breed 属性。
  不要将 [FromBody] 应用于每个操作方法的多个参数。 输入格式化程序读取请求流后,无法再次读取该流以绑定其他 [FromBody] 参数。 其他源
  源数据由"值提供程序"提供给模型绑定系统。 你可以编写并注册自定义值提供程序,这些提供程序从其他源中获取用于模型绑定的数据。 例如,你可能希望数据来自 cookie 或 会话状态。 要从新的源中获取数据,请执行以下操作: 创建用于实现 IValueProvider 的类。 创建用于实现 IValueProviderFactory 的类。 在 Startup.ConfigureServices 中注册工厂类。
  示例应用包括从获取值的值提供程序和工厂 cookie 示例。 以下是 Startup.ConfigureServices 中的注册代码:
  services.AddRazorPages()     .AddMvcOptions(options => {     options.ValueProviderFactories.Add(new CookieValueProviderFactory());     options.ModelMetadataDetailsProviders.Add(         new ExcludeBindingMetadataProvider(typeof(System.Version)));     options.ModelMetadataDetailsProviders.Add(         new SuppressChildValidationMetadataProvider(typeof(System.Guid))); }) .AddXmlSerializerFormatters();
  所示代码将自定义值提供程序置于所有内置值提供程序之后。 要将其置于列表中的首位,请调用 Insert(0, new CookieValueProviderFactory()) 而不是 Add。 不存在模型属性的源
  默认情况下,如果找不到模型属性的值,则不会创建模型状态错误。 该属性设置为 NULL 或默认值: 可以为 Null 的简单类型设置为 null。 不可以为 Null 的值类型设置为 default(T)。 例如,参数 int id 设置为 0。 对于复杂类型,模型绑定使用默认构造函数来创建实例,而不设置属性。 数组设置为 Array.Empty(),但 byte[] 数组设置为 null。
  如果在模型属性的窗体字段中未找到任何内容时模型状态应失效,请使用 [BindRequired] 特性。
  请注意,此 [BindRequired] 行为适用于发布的表单数据中的模型绑定,而不适用于请求正文中的 JSON 或 XML 数据。 请求正文数据由输入格式化程序进行处理。 类型转换错误
  如果找到源,但无法将其转换为目标类型,则模型状态将被标记为无效。 目标参数或属性设置为 NULL 或默认值,如上一部分所述。
  在具有 [ApiController] 属性的 API 控制器中,无效的模型状态会导致自动 HTTP 400 响应。
  在 Razor 页面中,重新显示页面并显示一条错误消息:
  public IActionResult OnPost() {     if (!ModelState.IsValid)     {         return Page();     }      _instructorsInMemoryStore.Add(Instructor);     return RedirectToPage("./Index"); }
  客户端验证将捕获大多数提交到 Razor 页面窗体的错误数据。 此验证使得先前突出显示的代码难以被触发。 示例应用包含一个"提交无效日期"按钮,该按钮将错误数据置于"雇用日期"字段中并提交表单。 此按钮显示在发生数据转换错误时用于重新显示页的代码将如何工作。
  在使用先前的代码重新显示页时,表单域中不会显示无效的输入。 这是因为模型属性已设置为 NULL 或默认值。 无效输入会出现在错误消息中。 但是,如果要在表单域中重新显示错误数据,可以考虑将模型属性设置为字符串并手动执行数据转换。
  如果不希望发生类型转换错误导致模型状态错误的情况,建议使用相同的策略。 在这种情况下,将模型属性设置为字符串。 简单类型
  模型绑定器可以将源字符串转换为以下简单类型: 布尔值 字节、SByte Char DateTime DateTimeOffset 十进制 双精度 Enum Guid Int16、Int32、Int64 Single TimeSpan UInt16、UInt32、UInt64 Uri 版本 复杂类型
  复杂类型必须具有要绑定的公共默认构造函数和公共可写属性。 进行模型绑定时,将使用公共默认构造函数来实例化类。
  对于复杂类型的每个属性,模型绑定会查找名称模式 prefix.property_name 的源。 如果未找到,它将仅查找不含前缀的 properties_name。
  对于绑定到参数,前缀是参数名称。 对于绑定到 PageModel 公共属性,前缀是公共属性名称。 某些属性具有 Prefix 属性,让你可以替代参数或属性名称的默认用法。
  例如,假设复杂类型是以下 Instructor 类:
  public class Instructor {     public int ID { get; set; }     public string LastName { get; set; }     public string FirstName { get; set; } } 前缀 = 参数名称
  如果要绑定的模型是一个名为 instructorToUpdate 的参数:
  public IActionResult OnPost(int? id, Instructor instructorToUpdate)
  模型绑定从查找键 instructorToUpdate.ID 的源开始操作。 如果未找到,它将查找不含前缀的 ID。 前缀 = 属性名称
  如果要绑定的模型是控制器或 PageModel 类的一个名为 Instructor 的属性:
  [BindProperty] public Instructor Instructor { get; set; }
  模型绑定从查找键 Instructor.ID 的源开始操作。 如果未找到,它将查找不含前缀的 ID。 自定义前缀
  如果要绑定的模型是名为 instructorToUpdate 的参数,并且 Bind 属性指定 Instructor 作为前缀:
  public IActionResult OnPost(     int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
  模型绑定从查找键 Instructor.ID 的源开始操作。 如果未找到,它将查找不含前缀的 ID。 复杂类型目标的属性
  多个内置属性可用于控制复杂类型的模型绑定: [Bind] [BindRequired] [BindNever]
  警告
  如果发布的表单数据是值的源,则这些属性会影响模型绑定。 它们  不  影响输入格式化程序,后者处理已发布的 JSON 和 XML 请求正文。 输入格式化程序的解释位于本文后面部分。 [Bind] 属性
  可应用于类或方法参数。 指定模型绑定中应包含的模型属性。 [Bind] 不  影响输入  格式化程序。
  在下面的示例中,当调用任意处理程序或操作方法时,只绑定 Instructor 模型的指定属性:
  [Bind("LastName,FirstMidName,HireDate")] public class Instructor
  在下面的示例中,当调用 OnPost 方法时,只绑定 Instructor 模型的指定属性:
  [HttpPost] public IActionResult OnPost([Bind("LastName,FirstMidName,HireDate")] Instructor instructor)
  [Bind] 属性可用于防止"创建"方案中的过多发布情况。 由于排除的属性设置为 NULL 或默认值,而不是保持不变,因此它在编辑方案中无法很好地工作。 为防止过多发布,建议使用视图模型,而不是使用 [Bind] 属性。 有关详细信息,请参阅有关过多发布的安全性说明。 [ModelBinder] 属性
  ModelBinderAttribute 可应用于类型、属性或参数。 它允许指定用于绑定特定实例或类型的模型绑定器的类型。 例如:
  [HttpPost] public IActionResult OnPost([ModelBinder(typeof(MyInstructorModelBinder))] Instructor instructor)
  [ModelBinder]当属性或参数处于模型绑定时,该属性还可用于更改属性或参数的名称:
  public class Instructor {     [ModelBinder(Name = "instructor_id")]     public string Id { get; set; }      public string Name { get; set; } } [BindRequired] 属性
  只能应用于模型属性,不能应用于方法参数。 如果无法对模型属性进行绑定,则会导致模型绑定添加模型状态错误。 下面是一个示例:
  public class InstructorWithCollection {     public int ID { get; set; }      [DataType(DataType.Date)]     [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]     [Display(Name = "Hire Date")]     [BindRequired]     public DateTime HireDate { get; set; }
  另请参阅模型验证中针对 [Required] 属性的讨论。 [BindNever] 属性
  只能应用于模型属性,不能应用于方法参数。 防止模型绑定设置模型的属性。 下面是一个示例:
  public class InstructorWithDictionary {     [BindNever]     public int ID { get; set; } 集合
  对于是简单类型集合的目标,模型绑定将查找 parameter_name 或 property_name 的匹配项。 如果找不到匹配项,它将查找某种不含前缀的受支持的格式。 例如: 假设要绑定的参数是名为 selectedCourses 的数组:C#复制 public  IActionResult OnPost (int ? id, int [] selectedCourses)表单或查询字符串数据可以采用以下某种格式:复制selectedCourses=1050&selectedCourses=2000 复制selectedCourses[0]=1050&selectedCourses[1]=2000 复制[0]=1050&[1]=2000 复制selectedCourses[a]=1050&selectedCourses[b]=2000&selectedCourses.index=a&selectedCourses.index=b 复制[a]=1050&[b]=2000&index=a&index=b 只有表单数据支持以下格式:复制selectedCourses[]=1050&selectedCourses[]=2000 对于前面所有的示例格式,模型绑定将两个项的数组传递给 selectedCourses 参数:selectedCourses[0]=1050selectedCourses[1]=2000使用下标数字的数据格式 (... [0] ... [1] ...) 必须确保从零开始按顺序进行编号。 如果下标编号中存在任何间隔,则间隔后的所有项都将被忽略。 例如,如果下标是 0 和 2,而不是 0 和 1,则第二个项会被忽略。 字典
  对于 Dictionary 目标,模型绑定会查找 parameter_name 或 property_name 的匹配项。 如果找不到匹配项,它将查找某种不含前缀的受支持的格式。 例如: 假设目标参数是名为 selectedCourses 的 Dictionary:C#复制 public  IActionResult OnPost (int ? id, Dictionary<int, string > selectedCourses)发布的表单或查询字符串数据可以类似于以下某一示例:复制selectedCourses[1050]=Chemistry&selectedCourses[2000]=Economics 复制[1050]=Chemistry&selectedCourses[2000]=Economics 复制selectedCourses[0].Key=1050&selectedCourses[0].Value=Chemistry& selectedCourses[1].Key=2000&selectedCourses[1].Value=Economics 复制[0].Key=1050&[0].Value=Chemistry&[1].Key=2000&[1].Value=Economics 对于前面所有的示例格式,模型绑定将两个项的字典传递给 selectedCourses 参数:selectedCourses["1050"]="Chemistry"selectedCourses["2000"]="Economics" 构造函数绑定和记录类型
  模型绑定要求复杂类型具有无参数的构造函数。 System.Text.Json和 Newtonsoft.Json 基于的输入格式化程序都支持对不具有无参数构造函数的类进行反序列化。
  C # 9 引入了记录类型,这是一个很好的方法,可以在网络上简洁地表示数据。 ASP.NET Core 增加了对模型绑定和使用单个构造函数验证记录类型的支持:
  public record Person([Required] string Name, [Range(0, 150)] int Age, [BindNever] int Id);  public class PersonController {    public IActionResult Index() => View();     [HttpPost]    public IActionResult Index(Person person)    {        ...    } }
  Person/Index.cshtml:
  @model Person  Name:  ... Age: 
  在验证记录类型时,运行时将搜索专用于参数而不是属性的绑定和验证元数据。
  该框架允许绑定到记录类型并对其进行验证:
  public record Person([Required] string Name, [Range(0, 100)] int Age);
  若要运行上述操作,类型必须: 为记录类型。 正好有一个公共构造函数。 包含具有相同名称和类型的属性的参数。 名称不得区分大小写。 无参数构造函数的 Poco
  不能绑定没有无参数构造函数的 Poco。
  下面的代码会引发异常,指出类型必须具有无参数的构造函数:
  public class Person(string Name)  public record Person([Required] string Name, [Range(0, 100)] int Age) {    public Person(string Name) : this (Name, 0); } 记录类型与手动编写的构造函数
  具有类似于主构造函数的手动创作构造函数的记录类型工作
  public record Person {    public Person([Required] string Name, [Range(0, 100)] int Age) => (this.Name, this.Age) = (Name, Age);     public string Name { get; set; }    public int Age { get; set; } } 记录类型、验证和绑定元数据
  对于记录类型,使用参数上的验证和绑定元数据。 忽略属性上的任何元数据
  public record Person (string Name, int Age) {    [BindProperty(Name = "SomeName")] // This does not get used    [Required] // This does not get used    public string Name { get; init; } } 验证和元数据
  验证使用参数的元数据,但使用属性来读取值。 在带有主构造函数的普通情况下,两者都是相同的。 不过,有几种方法可以实现此操作:
  public record Person([Required] string Name) {    private readonly string _name;    public Name { get; init => _name = value ?? string.Empty; } // Now this property is never null. However this object could have been constructed as `new Person(null);` } TryUpdateModel 不更新记录类型上的参数
  public record Person(string Name) {    public int Age { get; set; } }  var person = new Person("initial-name"); TryUpdateModel(person, ...);
  在这种情况下,MVC 不会尝试 Name 重新绑定。 但 Age 允许更新 模型绑定路由数据和查询字符串的全球化行为
  ASP.NET Core 路由值提供程序和查询字符串值提供程序: 将值视为固定区域性。 URL 的区域性应固定。
  相反,来自窗体数据的值要进行区分区域性的转换。 这是设计使然,目的是让 URL 可在各个区域设置中共享。
  使 ASP.NET Core 路由值提供程序和查询字符串值提供程序进行区分区域性的转换: 继承自 IValueProviderFactory 从 QueryStringValueProviderFactory 或 RouteValueValueProviderFactory 复制代码 使用 CultureInfo.CurrentCulture 替换传递给值提供程序构造函数的区域性值 将 MVC 选项中的默认值提供程序工厂替换为新的工厂:
  public void ConfigureServices(IServiceCollection services) {     services.AddControllersWithViews(options =>     {         var index = options.ValueProviderFactories.IndexOf(             options.ValueProviderFactories.OfType().Single());         options.ValueProviderFactories[index] = new CulturedQueryStringValueProviderFactory();     }); }
  public class CulturedQueryStringValueProviderFactory : IValueProviderFactory {     public Task CreateValueProviderAsync(ValueProviderFactoryContext context)     {         if (context == null)         {             throw new ArgumentNullException(nameof(context));         }          var query = context.ActionContext.HttpContext.Request.Query;         if (query != null && query.Count > 0)         {             var valueProvider = new QueryStringValueProvider(                 BindingSource.Query,                 query,                 CultureInfo.CurrentCulture);              context.ValueProviders.Add(valueProvider);         }          return Task.CompletedTask;     } } 特殊数据类型
  模型绑定可以处理某些特殊的数据类型。 IFormFile 和 IFormFileCollection
  HTTP 请求中包含的上传文件。 还支持多个文件的 IEnumerable。 CancellationToken
  操作可以选择将 CancellationToken 作为参数绑定。 这会将信号绑定到 RequestAborted HTTP 请求的基础的连接中止时。 操作可以使用此参数来取消长时间运行的异步操作,这些操作将作为控制器操作的一部分执行。 FormCollection
  用于从发布的表单数据中检索所有的值。 输入格式化程序
  请求正文中的数据可以是 JSON、XML 或其他某种格式。 要分析此数据,模型绑定会使用配置为处理特定内容类型的输入格式化程序。 默认情况下,ASP.NET Core 包括用于处理 JSON 数据的基于 JSON 的输入格式化程序。 可以为其他内容类型添加其他格式化程序。
  ASP.NET Core 基于 Consumes 属性来选择输入格式化程序。 如果没有属性,它将使用 Content-Type 标头。
  要使用内置 XML 输入格式化程序,请执行以下操作: 安装 Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet 包。 在 Startup.ConfigureServices 中,调用 AddXmlSerializerFormatters 或 AddXmlDataContractSerializerFormatters。C#复制services.AddRazorPages() .AddMvcOptions(options => { options.ValueProviderFactories.Add( new  CookieValueProviderFactory()); options.ModelMetadataDetailsProviders.Add( new  ExcludeBindingMetadataProvider(typeof (System.Version))); options.ModelMetadataDetailsProviders.Add( new  SuppressChildValidationMetadataProvider(typeof (System.Guid))); }) .AddXmlSerializerFormatters();将 Consumes 属性应用于应在请求正文中使用 XML 的控制器类或操作方法。C#复制[ HttpPost ] [Consumes( "application/xml" )] public  ActionResult Create (Pet pet) 有关更多信息,请参阅 XML 序列化简介。使用输入格式化程序自定义模型绑定
  由输入格式化程序完全负责从请求正文读取数据。 若要自定义此过程,请配置输入格式化程序使用的 API。 此部分介绍如何自定义基于 System.Text.Json 的输入格式化程序,以了解自定义类型 ObjectId。
  以包含自定义 ObjectId 属性 Id 的模型为例:
  public class ModelWithObjectId {     public ObjectId Id { get; set; } }
  使用 System.Text.Json 时,若要自定义模型绑定过程,请创建派生自 JsonConverter 的类:
  internal class ObjectIdConverter : JsonConverter {     public override ObjectId Read(         ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)     {         return new ObjectId(JsonSerializer.Deserialize(ref reader, options));     }      public override void Write(         Utf8JsonWriter writer, ObjectId value, JsonSerializerOptions options)     {         writer.WriteNumberValue(value.Id);     } }
  将 JsonConverterAttribute 属性应用到此类型,以使用自定义转换器。 在下面的示例中,为 ObjectId 类型配置了 ObjectIdConverter 来作为其自定义转换器:
  [JsonConverter(typeof(ObjectIdConverter))] public struct ObjectId {     public ObjectId(int id) =>         Id = id;      public int Id { get; } }
  有关详细信息,请参阅如何编写自定义转换器。 从模型绑定中排除指定类型
  模型绑定和验证系统的行为由 ModelMetadata 驱动。 可通过向 MvcOptions.ModelMetadataDetailsProviders 添加详细信息提供程序来自定义 ModelMetadata。 内置详细信息提供程序可用于禁用指定类型的模型绑定或验证。
  要禁用指定类型的所有模型的模型绑定,请在 Startup.ConfigureServices 中添加 ExcludeBindingMetadataProvider。 例如,禁用对 System.Version 类型的所有模型的模型绑定:
  services.AddRazorPages()     .AddMvcOptions(options => {     options.ValueProviderFactories.Add(new CookieValueProviderFactory());     options.ModelMetadataDetailsProviders.Add(         new ExcludeBindingMetadataProvider(typeof(System.Version)));     options.ModelMetadataDetailsProviders.Add(         new SuppressChildValidationMetadataProvider(typeof(System.Guid))); }) .AddXmlSerializerFormatters();
  要禁用指定类型的属性的验证,请在 Startup.ConfigureServices 中添加 SuppressChildValidationMetadataProvider。 例如,禁用对 System.Guid 类型的属性的验证:
  services.AddRazorPages()     .AddMvcOptions(options => {     options.ValueProviderFactories.Add(new CookieValueProviderFactory());     options.ModelMetadataDetailsProviders.Add(         new ExcludeBindingMetadataProvider(typeof(System.Version)));     options.ModelMetadataDetailsProviders.Add(         new SuppressChildValidationMetadataProvider(typeof(System.Guid))); }) .AddXmlSerializerFormatters(); 自定义模型绑定器
  通过编写自定义模型绑定器,并使用 [ModelBinder] 属性为给定目标选择该模型绑定器,可扩展模型绑定。 详细了解自定义模型绑定。 手动模型绑定
  可以使用 TryUpdateModelAsync 方法手动调用模型绑定。 ControllerBase 和 PageModel 类上均定义了此方法。 方法重载允许指定要使用的前缀和值提供程序。 如果模型绑定失败,该方法返回 false。 下面是一个示例:
  if (await TryUpdateModelAsync(     newInstructor,     "Instructor",     i => i.FirstMidName, i => i.LastName, i => i.HireDate)) {     _instructorsInMemoryStore.Add(newInstructor);     return RedirectToPage("./Index"); } PopulateAssignedCourseData(newInstructor); return Page();
  TryUpdateModelAsync 使用值提供程序从窗体正文、查询字符串和路由数据获取数据。 TryUpdateModelAsync 通常有以下特点: 与 Razor 使用控制器和视图的页面和 MVC 应用一起使用,以防止过度发布。 不用于 Web API(除非窗体数据、查询字符串和路由数据使用它)。 使用 JSON 的 Web API 终结点使用输入格式化程序将请求正文反序列化为对象。
  有关详细信息,请参阅 TryUpdateModelAsync。 [FromServices] 属性
  此属性的名称遵循指定数据源的模型绑定属性的模式。 但这与绑定来自值提供程序的数据无关。 它从依赖关系注入容器中获取类型的实例。 其目的在于,在仅当调用特定方法时需要服务的情况下,提供构造函数注入的替代方法。

努比亚Play5G手机及生态产品强势亮相2020年4月21日,刚刚进行完品牌升级的努比亚面向全网正式召开了努比亚Play5G手机新品发布会,在发布会上全新的努比亚将品牌对于5G移动通信终端的理解,与年轻化的形象以及为用户亚马逊利用第三方卖家的数据推自有品牌新品引发行业忧虑华尔街日报(WallStreetJournal)的一项调查发现,亚马逊利用其庞大的第三方卖家网络的数据来确定它将推出哪些新产品。调查发现,一些亚马逊高管获得了卖家数据,然后用来发现亚马逊发布了新品方便用户在AWS和SaaS之间传数据AWS今天发布了新产品AmazonAppFlow,这是一项新的集成服务,可以让开发者更容易地在AWS和SaaS应用程序之间传输数据,比如GoogleAnalyticsMarketo迷之魔幻般存在的老张拉面几年前就有所耳闻,今日得见,果然名不虚传,外面排起了长队,一向急躁的我为了这口面也破例加入了人群!队伍缓缓移动,大概排了有半个多小时,一家面馆,竟然还衍生出了代购,我也是头一次见到基础知识篇玩TikTok可能会遇到一些问题和解决方法目前,很多华南华东的卖家们,已经开始把鸡蛋放在不同的篮子里,比如很多卖家开始关注和重视韩国日本东南亚等国家,也有卖家布局一些小平台。紧随Instagram之后,TikTok被调查为出口总额保持在30亿美元以上,这类爆款在冬天很畅销在大洋彼岸,一年一度的海外消费者的年终狂欢节也即将到来,秉着要风度也要温度的原则,很多消费者喜欢在基础的服装上加上喜欢的上帽子围巾手套假发等配饰,能提供保暖的同时还能增加时尚感以及刚刚!Facebook宣布改名为Meta,未来重点开发元宇宙就在刚刚!Facebook改名了!昨天(10月28日周四),Facebook的首席执行官扎克伯格(MarkZuckerberg)在该公司的Connect发布会上宣布,该社交媒体平台独步天下,站领未来,2021独立站私域流量大会带你解锁新征途2020年伊始,跨境电商独立站的旗帜,一直傲然挺立在跨境电商大船的前方,虽然受到疫情肆虐以及被身材魁梧的船员打压与争抢,旗面或许有些破败,但丝毫不影响它在船员们心中的地位。国内,商BrandRegistry卖家真香众多亚马逊赚钱利器,爆单秘诀?近日,为帮助BrandRegistry注册并在亚马逊美国商店销售的品牌卖家品牌建立及客户关系维护。亚马逊推出一系列新的品牌工具服务和福利来助力卖家提高销售和盈利水平!01hrgetShopee又出直播通话功能LivestreamCall新功能Shopee又出新功能,直播通话功能LivestreamCallShopee直播宣布推出LivestreamCall直播通话功能,提高直播环节的参与度,以增强客户体验。在直播通话时亚马逊旺季广告投放技巧与旺季运营10条建议一种是影响型广告,包括有帖子视频直播亚马逊DSP,以及品牌旗舰店,该类型广告主要用故事来吸引品牌潜在购买者,使购买者关注其品牌并产生购买意愿。另一种是推动型广告,包括有商品推广品牌
实体店客流少拓客难?巧用小程序实现线上线下销量双增长由于现在实体店同质化严重,竞争激烈,因此客源越来越少,拓客极难,商家入不敷出,面临倒闭的威胁,商家怎样才能改变现状呢?一实体店客流少拓客难的原因1没有精准的用户数据来源,找不到合适私域电商增长方法论私域流量池的搭建,实现裂变的底层逻辑根据工信部持续加大对个人用户信息的保护,如今,阿里抖音等各大电商平台都明确表示平台将逐渐加大对数据安全的管控。从电商经营上,这也代表着我们不能像以往那样很方便地获取客户的关键信息了水果店小程序运营策略如何扩大获客渠道,实现业绩增长?对于高频消费的水果店,有很多门店的经营并不理想,同行竞争激烈,搞一波降价促销只能吸引一波流程,之后还是无人问津。仅仅依托线下门店坐等客户上门的方式,是远远不够的,商家还需主动扩大获鲜花店布局小程序线上渠道,高效拓客拯救销量的解决方案来了在众多礼品中,鲜花无疑是人们的最佳礼品选择之一,几乎可以在任何节庆或特殊场合作为礼品赠送。除了送礼,鲜花也成为家居生活装饰的点睛之笔。这也是为什么鲜花行业会愈发的火爆,无论是线下实没有搭建经验的新手小白,怎样搭建适合自己的微信小程序?越来越多的商家通过得有店搭建出了属于自己的小程序店铺,实现了线上经营,但是仍然有一部分没有搭建经验的商家,由于对小程序不了解,不了解线上经营的功能需求,不知道应该搭建一个什么类型的实体店如何利用小程序转型新零售?小程序有哪些应用类型?实体店转型新零售势不可挡,从近两年的行业发展就可看出其中端倪,但是如何转型又成了一大问题,根据这一问题,我们来一一梳理一下。一什么是新零售?新零售其实就是顺应时代发展而产生的一种新拓客引流难已成行业通病,实体店如何打破现状成功出圈?如今的线下实体店都面临着同一个问题,那就是客源,客源的多少直接影响店铺的销量与利润,因此如何引流拓客成了关键。一实体店拓客引流难的原因1服务范围有限2客户易流失3运营成本节节攀升4实体店想增加销售渠道,并把客户牢牢抓住,借助小程序该怎么做?单靠实体店,无法有效做到客户的拉新和留存工作,利润大幅下滑。不管线上还是线下,生意的本质就是流量,客源就是长久发展的根本。相对纯电商而言,实体店有天然的线下优势,那我们获客和留存客鲜花小程序开发案例看它是如何搭建的,这些营销思路值得借鉴鲜花行业利用小程序实现销售转型已经屡见不鲜,但是如何真正将小程序利用得恰到好处是需要钻研的,鲜花行业小程序案例花千古,对于同行业商家来说,还是值得借鉴的,下面,就让我们一起来学习一不懂小程序运营推广?这篇攻略教你实现用户裂变式增长小程序运营很难吗?对于没有接触过小程序的商家来说,运营是需要技巧的,下面就让我来告诉你,如何高效运营小程序,实现用户裂变式增长。一小程序运营目的让更多的用户了解知道你的小程序,在提为什么用了小程序客流还是上不去?你确定方法用对了吗?很多商家想拓宽销售渠道,而利用得有店搭建了属于自己的小程序店铺,实现线上经营,但是搭建完成之后却又出现了新的问题,那就是客流问题。很多商家都想知道,为什么用了小程序客流还是上不去,