webapi - ASP.NET MVC-인터페이스 유형의 사용자 정의 모델 바인더




frombody attribute (2)

이 동작이 예상되는지 확실하지 않지만 바인딩이 인터페이스 유형에 할당 될 때 사용자 지정 모델 바인딩이 작동하지 않는 것처럼 보입니다. 이걸 가지고 실험 한 사람 있니?

public interface ISomeModel {}
public class SomeModel : ISomeModel {}

public class MvcApplication : HttpApplication {
    protected void Application_Start(object sender, EventArgs e) {
        ModelBinders.Binders[typeof(ISomeModel)] = new MyCustomModelBinder();
    }
}

위 코드를 사용하면 SomeModel 유형의 모델에 바인딩 할 때 MyCustomModelBinder가 절대 적중되지 않습니다. 그러나 위 코드를 변경하고 typeof(ISomeModel)typeof(SomeModel) 대체하고 똑같은 양식을 게시하면 MyCustomModelBinder가 예상대로 호출됩니다. 그럴 것 같니?

편집하다

나는 원래이 질문을한지 1 년이 지난 후에 나 자신을 발견했고 지금은 해결할 수있는 해결책이있다. Matt Hidinger에게 감사드립니다!

http://www.matthidinger.com/archive/2011/08/16/An-inheritance-aware-ModelBinderProvider-in-MVC-3.aspx



나는이 문제를 실험하고 있었고 나는 일종의 해결책을 찾았다. InterfaceModelBinder라는 클래스를 만들었습니다.

public class InterfaceModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        ModelBindingContext context = new ModelBindingContext(bindingContext);
        var item = Activator.CreateInstance(
            Type.GetType(controllerContext.RequestContext.HttpContext.Request.Form["AssemblyQualifiedName"]));

        Func<object> modelAccessor = () => item;
        context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),
            bindingContext.ModelMetadata.ContainerType, modelAccessor, item.GetType(), bindingContext.ModelName);

        return base.BindModel(controllerContext, context);
    }
}

내 Application_Start에 등록한 사람 :

ModelBinders.Binders.Add(typeof(IFormSubmission), new InterfaceModelBinder.Models.InterfaceModelBinder());

인터페이스와 구체적인 구현은 다음과 같습니다.

public interface IFormSubmission
{
}

public class ContactForm : IFormSubmission
{
    public string Name
    {
        get;
        set;
    }

    public string Email
    {
        get;
        set;
    }

    public string Comments
    {
        get;
        set;
    }
}

이 전체 접근 방식의 유일한 단점은 (이미 모았 듯이) 어딘가에서 AssemblyQualifiedName을 가져와야한다는 것이며,이 예제에서는 클라이언트 측에 숨겨진 필드로 저장된다는 것입니다.

<%=Html.HiddenFor(m => m.GetType().AssemblyQualifiedName) %>

Type 이름을 클라이언트에 노출시키는 단점은이 접근 방식의 이점을 잃어 버릴 가치가 있지만 확실하지 않습니다. 이와 같은 액션은 모든 양식 제출을 처리 할 수 ​​있습니다.

[HttpPost]
public ActionResult Process(IFormSubmission form)
{
    if (ModelState.IsValid)
    {
        FormManager manager = new FormManager();
        manager.Process(form);
    }

    //do whatever you want
}

이 접근법에 대한 생각은?





modelbinders