Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
170 views
in Technique[技术] by (71.8m points)

c# - Web API form-urlencoded binding to different property names

I am expecting a POST request with content type set to:

Content-Type: application/x-www-form-urlencoded

Request body looks like this:

first_name=john&last_name=banana

My action on controller has this signature:

[HttpPost]
public HttpResponseMessage Save(Actor actor)
{
    ....
}

Where Actor class is given as:

public class Actor
{
public string FirstName {get;set;}
public string LastName {get;set;}
}

Is there a way to force Web API to bind:

first_name => FirstName
last_name => LastName

I know how to do it with requests with content type set to application/json, but not with urlencoded.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm 98% certain (I looked the source code) that WebAPI doesn't support it.

If you really need to support different property names, you can either:

  1. Add additional properties to the Actor class which serves as alias.

  2. Create your own model binder.

Here is a simple model binder:

public sealed class ActorDtoModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var actor = new Actor();

        var firstNameValueResult = bindingContext.ValueProvider.GetValue(CreateFullPropertyName(bindingContext, "First_Name"));
        if(firstNameValueResult != null) {
            actor.FirstName = firstNameValueResult.AttemptedValue;
        }

        var lastNameValueResult = bindingContext.ValueProvider.GetValue(CreateFullPropertyName(bindingContext, "Last_Name"));
        if(lastNameValueResult != null) {
            actor.LastName = lastNameValueResult.AttemptedValue;
        }

        bindingContext.Model = actor;

        bindingContext.ValidationNode.ValidateAllProperties = true;

        return true;
    }

    private string CreateFullPropertyName(ModelBindingContext bindingContext, string propertyName)
    {
        if(string.IsNullOrEmpty(bindingContext.ModelName))
        {
            return propertyName;
        }
        return bindingContext.ModelName + "." + propertyName;
    }
}

If you are up for the challenge, you can try to create a generic model binder.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...