<p>I have deployed a simple dotnet core app into Kubernetes. The service which is exposed is as below </p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2020-01-17T18:07:23Z"
  labels:
    app.kubernetes.io/instance: expo-api
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: expo-api
    app.kubernetes.io/version: 0.0.4
    helm.sh/chart: expo-api-0.0.4
  name: expo-api-service
  namespace: default
  resourceVersion: "997971"
  selfLink: /api/v1/namespaces/default/services/expo-api-service
  uid: 144b9d1d-87d2-4096-9851-9563266b2099
spec:
  clusterIP: 10.12.0.122
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  selector:
    app.kubernetes.io/instance: expo-api
    app.kubernetes.io/name: expo-api
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
</code></pre>

<p>The ingress controller I am using is nginx ingress controller and the simple ingress rules are set as below - </p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: "true"
  creationTimestamp: "2020-01-17T18:07:24Z"
  generation: 3
  labels:
    app.kubernetes.io/instance: expo-api
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: expo-api
    app.kubernetes.io/version: 0.0.4
    helm.sh/chart: expo-api-0.0.4
  name: expo-api
  namespace: default
  resourceVersion: "1004650"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/expo-api
  uid: efef4e15-ed0a-417f-8b34-4e0f46cb1e70
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: expo-api-service
          servicePort: 80
        path: /expense
status:
  loadBalancer:
    ingress:
    - ip: 34.70.45.62
</code></pre>

<p>The dotnet core app which has a simple start up - </p>

<pre><code>public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =&gt;
            {
                endpoints.MapControllers();
            });
        }
    }
</code></pre>

<p>This is the ingress output - </p>

<pre><code>Name:             expo-api
Namespace:        default
Address:          34.70.45.62
Default backend:  default-http-backend:80 (10.8.0.9:8080)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     
        /expense   expo-api-service:80 (10.8.0.26:80,10.8.0.27:80,10.8.1.14:80)
Annotations:
  kubernetes.io/ingress.class:            nginx
  nginx.ingress.kubernetes.io/use-regex:  true
Events:                                   &lt;none&gt;
</code></pre>

<p>Below is the nginx ingress controller setup -</p>

<pre><code>Name:                     nginx-nginx-ingress-controller
Namespace:                default
Labels:                   app=nginx-ingress
                          chart=nginx-ingress-1.29.2
                          component=controller
                          heritage=Helm
                          release=nginx
Annotations:              &lt;none&gt;
Selector:                 app=nginx-ingress,component=controller,release=nginx
Type:                     LoadBalancer
IP:                       10.12.0.107
LoadBalancer Ingress:     34.66.164.70
Port:                     http  80/TCP
TargetPort:               http/TCP
NodePort:                 http  30144/TCP
Endpoints:                10.8.1.6:80
Port:                     https  443/TCP
TargetPort:               https/TCP
NodePort:                 https  30469/TCP
Endpoints:                10.8.1.6:443
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &lt;none&gt;
</code></pre>

<p>The issue is when I am changing the ingress rules path to only <code>/</code> and access using - <code>curl 34.66.164.70/weatherforecast</code> it works perfectly fine . </p>

<p>However when I change the ingress path to <code>/expense</code> and try to access using - curl <code>34.66.164.70/expense/weatherforecast</code> . The output is an error as - </p>

<pre><code>{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|4dec8cf0-4fddb4d168cb9569.",
  "errors": {
    "id": [
      "The value 'weatherforecast' is not valid."
    ]
  }
}
</code></pre>

<p>I am unable to understand what is the issue behind this. Whether it is appearing from dotnet core side or Kubernetes? If dotnet what may be the resolution and if on Kubernetes what is the expected resolution. </p>

<p><strong>ORIGINAL</strong> :Thanks to @heyzling insight I found out the solution to it . I changed the app path into the code <code>startup.cs</code>. The issue was the Api originally was not expecting a route prefix for all controllers . Hence it was giving the error . So that I had to do a slight change in the <code>startup.cs</code> to add <code>app.UsePathBase("/expense")</code> . Below is the configuration which I added - </p>

<pre><code>public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UsePathBase("/expense"); // this is the added configuration which identifies the ingress path rule individually. 
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =&gt;
            {
                endpoints.MapControllers();
            });
        }
</code></pre>

<p>Ideally I feel this is isn't a good design since kubernetes ingress and dotnet core routes should know nothing about each other . They ideally should not be dependent on each other to comply routing rules . If someone has better solution ? Please do post . The above one solves my purpose but I am not happy with it . </p>

<pre><code>----------------------------------------------------------------------------------
</code></pre>

<p><strong>UPDATE 2</strong>: Thanks to @heyzling . I finally found the solution - 
It looks like it had to rewrite the url and forward the actual API url which dotnet code expecting to the docker image which is running .</p>

<p>Here is the code example - </p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
  labels:
    app.kubernetes.io/name: expo-api
  name: expo-api
  namespace: default
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: expo-api-service
          servicePort: 80
          path: /expense(/|$)(.*)
</code></pre>

<p>So now you can do both -</p>

<pre><code>curl 35.192.198.231/expense/weatherforecast
curl 35.192.198.231/expense/fakeapi
</code></pre>

<p>it would rewrite and forward the url as -    </p>

<pre><code>localhost:80/weatherforecast
localhost:80/fakeapi
</code></pre>

<p>inside the container. Hence it works as expected . In that way we <code>DO NOT</code> require <code>app.UsePathBase("/expense")</code>  anymore and both dotnet core and ingress does not have to know anything about each other. </p>
