0
votes

I am using Azuren Search and Azure Table Storage and with .net and i am trying to index a table and make a partition key filterable now this works fine until i try to insert something in that table where i get a BadRequest with not much of additional info. This is my class bellow

using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Microsoft.WindowsAzure.Storage.Table;

      [SerializePropertyNamesAsCamelCase]
    public class Asset : TableEntity
    {
        public Asset(string name)
        {
            Name = name;
        }

        public Asset()
        {

        }

        public Asset(string name, DateTimeOffset toBePublished, string pkey)
        {
            Name = name;
            ToBePublishedDate = toBePublished;
            PartitionKey = pkey;
        }

        [System.ComponentModel.DataAnnotations.Key]
        public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
            .Replace("+", string.Empty)
            .Replace(":", string.Empty)
            .Replace(".", string.Empty);

        [IsFilterable, IsSortable, IsSearchable]
        public new string PartitionKey { get; set; }

        [IsFilterable, IsSortable, IsSearchable]
        public string Name { get; set; } = "TemptAsset " + new Guid();

        [IsFilterable, IsSortable]
        public int? Version { get; set; } = 1;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBeRetiredDate { get; set; } = null;

        [IsFilterable, IsSearchable, IsSortable]
        public string Company { get; set; } = "TempCompany";
        [IsFilterable, IsSortable]
        public bool IsApproved { get; set; } = false;

        [IsFilterable, IsSortable]
        public bool IsDraft { get; set; } = true;


    }

This runs and the index is created successfully see bellow enter image description here

Now if i try to add an entity to that table i get a BadRequest, but do the exact same thing with commenting out the PartitionKey in my entity and this works fine. This is how i create my index

AzureSearch.CreateAssetNameIndex(AzureSearch.CreateSearchServiceClient());

    and the methods called bellow




using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using AssetSynch.Models;
    using Microsoft.Azure.Search;
    using Microsoft.Azure.Search.Models;
      public static SearchServiceClient CreateSearchServiceClient()
        {
            string searchServiceName = "*****";
            string adminApiKey = "********";

            SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName,
                new SearchCredentials(adminApiKey));

            return serviceClient;
        }

    public static async void CreateAssetNameIndex(SearchServiceClient serviceClient)
        {
            Index definition = new Index
            {
                Name = "assetname",
                Fields = FieldBuilder.BuildForType<Asset>()
            };

            await serviceClient.Indexes.CreateAsync(definition);
        }

If i return the error using postman this is the exception i get

      {
  "innerExceptions": [
    {
      "requestInformation": {
        "httpStatusCode": 400,
        "httpStatusMessage": "Bad Request",
        "serviceRequestID": "59efbc9a-0002-002c-3570-d5d55c000000",
        "contentMd5": null,
        "etag": null,
        "requestDate": "Thu, 25 May 2017 17:05:01 GMT",
        "targetLocation": 0,
        "extendedErrorInformation": {
          "errorCode": "PropertiesNeedValue",
          "errorMessage": "The values are not specified for all properties in the entity.\nRequestId:59efbc9a-0002-002c-3570-d5d55c000000\nTime:2017-05-25T16:05:06.5197909Z",
          "additionalDetails": {}
        },
        "isRequestServerEncrypted": false
      }
    }
  ]
}

if i remove the Partition key from my entity and re run the same code to re-create the index the same piece of code this executes successfully. What i did noticed is that there are now 2 Partition keys on my entity one of which will remain null see image bellow and that my property does not override the original.

enter image description here

Is there something i am missing here?

1
You mentioned that you're using Azure Storage SDK but the code is for Search Service SDK. Can you please explain that?Gaurav Mantri
Sorry my bad on what i was thinking will typing i will fix thatHarry
If you're running this as a console app, you can trace the request/response in a tool like Fiddler. You should see more details about the error.Gaurav Mantri

1 Answers

1
votes

According to your codes, I find your Asset has used new keyword to modify the base class's partition property.

But this will just hidden the base.partition not override it.

public new string PartitionKey { get; set; }

After you set the value in the Asset class, you will find it contains two partition as below:

enter image description here

So if the base class's partition key value is null, it will return 400 error.

So if you want to add the new entity to the table, you need set the base class(TableEntity) partition key value.

So I suggest you could change your Asset as below:

  [SerializePropertyNamesAsCamelCase]
    public class Asset : TableEntity
    {
        public Asset(string name)
        {
            Name = name;
            base.PartitionKey = this.PartitionKey;
        }

        public Asset()
        {
            base.PartitionKey = this.PartitionKey;
        }

        public Asset(string name, DateTimeOffset toBePublished, string pkey)
        {

            Name = name;
            ToBePublishedDate = toBePublished;         
            PartitionKey = pkey;
            base.PartitionKey = this.PartitionKey;
        }

        [Key]
        [IsFilterable]
        public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
            .Replace("+", string.Empty)
            .Replace(":", string.Empty)
            .Replace(".", string.Empty);

        [IsFilterable, IsSortable, IsSearchable]
        public new string PartitionKey { get; set; }

        [IsFilterable, IsSortable, IsSearchable]
        public string Name { get; set; } = "TemptAsset " + new Guid();

        [IsFilterable, IsSortable]
        public int? Version { get; set; } = 1;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBeRetiredDate { get; set; } = null;

        [IsFilterable, IsSearchable, IsSortable]
        public string Company { get; set; } = "TempCompany";
        [IsFilterable, IsSortable]
        public bool IsApproved { get; set; } = false;

        [IsFilterable, IsSortable]
        public bool IsDraft { get; set; } = true;


    }

If you want to use table storage as datasource, I suggest you could refer to this article.