Getting my Custom Model bound to my POST controller

血红的双手。 提交于 2019-12-10 18:31:43

问题


I am using the recently released MVC 4 Beta (4.0.20126.16343) and am working on getting around a known problem with deserialization/model binding not working with arrays (see Stack Overflow here)

I am having difficulty getting my explicit custom binding to hook up. I have registered a custome IModelBinder (or attempted to) but when my post action is called my custom binder isn't hit and I just get the default serialization (with the null arrays - even though wireshark shows me the incoming complex object contains array elements).

I feel like I am missing something and would greatly appreciate any solution or insight.

Thanks.

from global.asax.cs:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

protected void Application_Start()
{
    ModelBinders.Binders.Add(typeof(DocuSignEnvelopeInformation), new DocusignModelBinder());
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();
}

and my custom binder:

public object BindModel(ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext)
{
    var value = bindingContext.ValueProvider.GetValue("envelope");

    var model = new DocuSignEnvelopeInformation();

    //build out the complex type here

    return model;
}

and my controller is just:

public void Post(DocuSignEnvelopeInformation envelope)
{
    Debug.WriteLine(envelope);
}

回答1:


Generally we register our Model Binders via DI container and it works. Register a IModelBinderProvider with DI container used by DependencyResolver and return your ModelBinder from there in the GetBinder method.




回答2:


This is what I ended up doing (thanks to Jimmy Bogard in Model binding XML in ASP.NET MVC 3)

I wound my solution back to MVC 3. (Burned by pre-release anxiety once again)

Added a ModelBinderProvider:

public class XmlModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
        var contentType = HttpContext.Current.Request.ContentType;

        if (string.Compare(contentType, @"text/xml",
            StringComparison.OrdinalIgnoreCase) != 0)
        {
            return null;
        }

        return new XmlModelBinder();
    }
}

and a ModelBinder

public class XmlModelBinder : IModelBinder
{
    public object BindModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        var modelType = bindingContext.ModelType;
        var serializer = new XmlSerializer(modelType);

        var inputStream = controllerContext.HttpContext.Request.InputStream;

        return serializer.Deserialize(inputStream);
    }
}

and added this to Application_Start():

    ModelBinderProviders.BinderProviders
    .Add(new XmlModelBinderProvider());

My controller stayed exactly the same as in the question.

Works like a treat. Will be great when the new 'no strings' approach arrives properly with MVC 4, but this manual binding approach to deserialization isn't exactly onerous.



来源:https://stackoverflow.com/questions/10643590/getting-my-custom-model-bound-to-my-post-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!