Tôi đang tìm kiếm một giải pháp trong đó tôi có thể sử dụng cùng một mô hình để chèn và cập nhật trong api web. Trong tình huống của tôi là điều này luôn luôn là một nội dung cơ thể. Các [Requiered]
thuộc tính phải được bỏ qua nếu nó là một phương thức cập nhật. Trong giải pháp của tôi, bạn đặt một thuộc tính [IgnoreRequiredValidations]
trên phương thức. Điều này như sau:
public class WebServiceController : ApiController
{
[HttpPost]
public IHttpActionResult Insert(SameModel model)
{
...
}
[HttpPut]
[IgnoreRequiredValidations]
public IHttpActionResult Update(SameModel model)
{
...
}
...
Những gì khác cần phải được thực hiện? Một BodyModelValidator riêng phải được tạo và thêm vào lúc khởi động. Đây là trong HTTPConfiguration và trông như thế này:config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());
using Owin;
using your_namespace.Web.Http.Validation;
[assembly: OwinStartup(typeof(your_namespace.Startup))]
namespace your_namespace
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
Configuration(app, new HttpConfiguration());
}
public void Configuration(IAppBuilder app, HttpConfiguration config)
{
config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());
}
...
BodyModelValidator của riêng tôi có nguồn gốc từ DefaultBodyModelValidator. Và tôi nhận ra rằng tôi đã phải ghi đè lên phương thức 'ShallowValidate'. Trong phần ghi đè này, tôi lọc các trình xác nhận mô hình certierd. Và bây giờ, lớp IgnoreRequiredOrDefaultBodyModelValidator và lớp attributte IgnoreRequiredValidations:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Metadata;
using System.Web.Http.Validation;
namespace your_namespace.Web.Http.Validation
{
public class IgnoreRequiredOrDefaultBodyModelValidator : DefaultBodyModelValidator
{
private static ConcurrentDictionary<HttpActionBinding, bool> _ignoreRequiredValidationByActionBindingCache;
static IgnoreRequiredOrDefaultBodyModelValidator()
{
_ignoreRequiredValidationByActionBindingCache = new ConcurrentDictionary<HttpActionBinding, bool>();
}
protected override bool ShallowValidate(ModelMetadata metadata, BodyModelValidatorContext validationContext, object container, IEnumerable<ModelValidator> validators)
{
var actionContext = validationContext.ActionContext;
if (RequiredValidationsIsIgnored(actionContext.ActionDescriptor.ActionBinding))
validators = validators.Where(v => !v.IsRequired);
return base.ShallowValidate(metadata, validationContext, container, validators);
}
#region RequiredValidationsIsIgnored
private bool RequiredValidationsIsIgnored(HttpActionBinding actionBinding)
{
bool ignore;
if (!_ignoreRequiredValidationByActionBindingCache.TryGetValue(actionBinding, out ignore))
_ignoreRequiredValidationByActionBindingCache.TryAdd(actionBinding, ignore = RequiredValidationsIsIgnored(actionBinding.ActionDescriptor as ReflectedHttpActionDescriptor));
return ignore;
}
private bool RequiredValidationsIsIgnored(ReflectedHttpActionDescriptor actionDescriptor)
{
if (actionDescriptor == null)
return false;
return actionDescriptor.MethodInfo.GetCustomAttribute<IgnoreRequiredValidationsAttribute>(false) != null;
}
#endregion
}
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class IgnoreRequiredValidationsAttribute : Attribute
{
}
}
Nguồn:
RequiredAttr
hoàn toàn và kiểm tra phía máy chủ khi bạn cần. Nhưng điều này sẽ gây khó khăn cho khách hàng