0
votes

I'm creating some Web API's for internal use and one of the 3rd party applications that will interact with it can only use odata v3 (i.e. not odata v4).

I'm trying to query another 3rd party application from this Web API - get a contact by email but not sure how to go about getting it by a string and not id.

I have a simplified model like so:

public class Contact
{
    [Key]
    public int Id { get; set; }
    public string Email { get; set; }
    public string CompanyName { get; set; }
}

Simplified controller:

public IHttpActionResult GetContact([FromODataUri] int key)
{
    var contact = _repository.GetContact(key);

    // return..
}

Simplified WebApiConfig

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
var container = new UnityContainer();
container.RegisterType<IContactRepository, ContactRepository>(new ContainerControlledLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
builder.EntitySet<Contact>("Contacts");
config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

If I look at the metadata document it shows Id as expected:

<EntityType Name="Contact">
<Key>
<PropertyRef Name="Id"/>
</Key>

In my model if I move the [Key] annotation to email and then in WebApiConfig change builder.EntitySet<Contact>("Contacts");

to

builder.EntitySet<Contact>("Contacts").EntityType.HasKey(c => c.Email); 

I also change the key input parameter in the controller from int to string it makes a composite key of Id and Email

<EntityType Name="Contact">
<Key>
<PropertyRef Name="Email"/>
<PropertyRef Name="Id"/>
</Key>

http://xxx:52759/odata/Contacts('[email protected]') works if I use fiddler to test but my 3rd party application reads the metadata and require me to pass in Id and Email, I don't have the Id at that time.

If I rename Id to something like cId in my model it's not part of the key in the metadata anymore but I don't think this is the right way to go about it?

<EntityType Name="Contact">
<Key>
<PropertyRef Name="Email"/>
</Key>

Am I on track or do I have to do something completely different if I want to get a contact by email (and in that way get id with the response back)?

Thanks in advance.

1
Is it possible you can just use a filter instead of modifying the entity keys? http://xxx:52759/odata/Contacts?$filter=Email eq '[email protected]'mitch

1 Answers

0
votes

You should pass int Id and Email is it is a composite key, in your scenario, I think your mean AlternateKey, which is suported in V4 https://github.com/OData/ODataSamples/tree/master/WebApi/v4/ODataAlternateKeySamples