0

I have a series of services I am configuring in my application and one of those services require a base URL to a specific route so I can create links based on it. So if we have:

My Controller

[Route("api/v1/fancy")]
public class FancyController {
  [HttpPost]
  [Route("{fancyID}")]
  public async Task<IActionResult> SubmitFancy(string fancyID){
    // Do fancy stuff
  }
}

My business class

public class Business {
  private string _baseUrl;
  public Business(string baseUrl){
    _baseUrl = baseUrl
  }
}

My Startup.cs

...
public void ConfigureServices(IServiceCollection services) {
  services.AddScoped<Business>(provider => {
    Business business = new Business("http://someweb.com/api/v1/fancy"); //TODO:REMOVE Hard Coded
    return business;
  }
  services.AddRazorPages();
}
...

I have tried to use UrlHelper by adding a few more scoped services for IActionContextAccessor and IUrlHelperFactory, but I am getting null on ActionLink and RouteUrl methods, and I am not sure why.

Any ideas as to how I would go about solving this issue?

Please let me know if you need more clarification.

Thank you very much.

Oakcool
  • 1,470
  • 1
  • 15
  • 33
  • Fun fact: A web server can receive traffic via any number of base URLs, e.g. if DNS points more than one domain at it. So the notion of a base URL really only makes sense in the context of an HTTP request. I suggest you render your links based on the [base URL in the request](https://stackoverflow.com/questions/1288046/how-can-i-get-my-webapps-base-url-in-asp-net-mvc) – John Wu Jul 20 '21 at 00:24

2 Answers2

0

You can't use a string for an attribute routing. You need a CONSTANT string. Constants are immutable values which are known at compile time and do not change for the life of the program.

But if you need a route to use in ajax or httpclient, it takes several steps to get a string from appsettings.

  1. create AppUrl section in appsettings.json
"AppUrl": {
    "BusinessUrl": "http//..",
     .... another urls if needed
   
},

2.Create class for this section

 public class AppUrlSettings
  {
        public string BusinessUrl{ get; set; }

        ....another urls
   }
  1. configure settings in startup
services.Configure<AppUrlSettings>(Configuration.GetSection("AppUrl"));
  1. now you can use them like this
public class MyClass
    {
        private readonly IOptions<AppUrlSettings> _appUrls;

        public MyClass (IOptions<AppUrlSettings> appUrls)
        {
            _appUrls = appUrls;
        }

        public string GetBusinessUrl()
        {
            return _appUrls.Value.BussinesUrl;
        }
}
Serge
  • 40,935
  • 4
  • 18
  • 45
0

Inject a LinkGenerator & IHttpContextAccessor into your service;

public class Business {
    private readonly LinkGenerator generator;
    private readonly IHttpContextAccessor accessor;
    public Business (LinkGenerator generator, IHttpContextAccessor accessor){...}

    public void Foo(){
        var context = accessor.HttpContext;
        var link = generator.GetUriByAction(
            context,
            "SubmitFancy",
            "Fancy", 
            new { fancyID="..." });
    }
}

services.AddScoped<Business>();

You can use LinkGenerator without a reference to a HttpContext, but you'd need to supply the host, scheme and pathBase from somewhere else. Either from configuration, or perhaps by implementing middleware to capture them from the first request.

Jeremy Lakeman
  • 9,515
  • 25
  • 29