1
votes

I have the following OData builder config. Which defines an Action Create with a few parameters. Note that I ignore the property Password. That's important later.

var userEntitySetName = nameof(UsersController).Replace("Controller", string.Empty);
var users = builder.EntitySet<User>(userEntitySetName);
users.EntityType.HasKey(x => x.Id);
users.EntityType.Ignore(x => x.Password);

var userCreateAction = users.EntityType.Collection.Action("Create").ReturnsFromEntitySet<User>(userEntitySetName);
userCreateAction.Parameter<int>("number");

I can then choose to do either

userCreateAction.EntityParameter<User>("user");

Or

userCreateAction.Parameter<User>("user");

The description for Parameter says: "Adds a new non-binding parameter". EntityParameter doesn't have a description. But I assume it's a binding parameter. Whatever that means. (Please explain)

More on these two choices later.

My User class

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public string Password { get; set; } // remember this is ignored
}

My controller action

[ODataRoute("Users/Create")]
public IHttpActionResult PostCreate(ODataActionParameters parameters)
{
    // omitted
}

My request payload

{
    "number": 1,
    "user":{ "FirstName": "foo", "LastName": "bar", "Password": "123" }
}

When I POST the above request parameters is null. However if I POST it without the ignored property Password then it works as expected.

This is where I assumed that using EntityParameter would use the User entity defined by the OData builder. The one without the Password property. And Parameter would use the actual User type, including the Password property. Allowing me to do the above request.

But that's not the case :(

So I'm confused about the difference between Parameter and EntityParameter. Can someone explain their intended use?

But hold on there's more. This is where I got really confused.

If I reduce the number of parameters to my action to only have the complex User type and change my controller action to:

[ODataRoute("Users/Create")]
public IHttpActionResult PostCreate(User user)
{
    // omitted
}

Then I can do a POST request with the Password property included. Note it's no longer wrapped in another object.

{ "FirstName": "foo", "LastName": "bar", "Password": "123" }

Which is nice. But I need the additional parameters :(

I guess the real question boils down to: "How can I POST ignored properties to my multi parameter action?"

Thanks


Update

I can't get the POST with Password to work anymore. I'm sure I had it working earlier. So please take the last part with a grain of salt. The question is still valid though :)

1

1 Answers

1
votes

The first question: EntityParameter also is adding an non-binding entity type parameter. If you add a binding entity type, it means you bind this action to a entity or entityset, see function: SetBindingParameter.

So why you use Parameter function can get password property? This is because when you call Parameter we will search User type in complex types and primitive types in your model and we can't get it, so we build a complex type for your User type using the CLR type which have password property, and use EntityParameter function will get the User entity type in the model which doesn't have the password property.