[Fixed] Pass data from Angular to .Net Core Web Api with "/" character

Issue

I have issue with passing data from angular to webapi.
I need to translate some phrases from my DB and everything works until my phrase looks like this:

"day w/o break"

Because in this situation my request to webapi looks like:

https://localhost:44973/api/translation/getResstring/day%20w/o%20break

And that character / destroying the request.
How to pass it to WebApi correctly? I did it in hurry yesterday do encode on Angular side and decode on Web Api side but it not works, so i decided to revert it.

Yesterday attempt, angular app:

[...]
public getResstringByPhrase(
source: string
): Observable<string> {
  const result = this.http.get(this.url + "getResstring/" + source, { responseType: 'text' })
  return result
}
[...]

.net Core web api:

[HttpGet("{*phrase}")]
[Route("getResstring/{phrase}")]
public IActionResult Get(string phrase)
{
  var resstring = _translationRepository.GetResstringByPhrase(phrase);
  return new OkObjectResult(resstring);
}

Startup.cs (only Configure):

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  if (env.IsDevelopment())
  {
    app.UseDeveloperExceptionPage();
  }

  app.UseHttpsRedirection();

  app.UseRouting();

  app.UseAuthorization();

  app.UseEndpoints(endpoints =>
  {
    endpoints.MapControllers();
  });

} }

But even with this attempt, it doesn’t work with phrases with "/" symbol

#UPDATE

Conflicting action:

   [HttpGet("{languageCharset}/{resstring}")]
    [Route("{languageCharset}/{resstring}")]
    public IActionResult Get(string resstring, LanguageCharset languageCharset)
    {
      var translate = _translationRepository.GetTranslatedByResstring(resstring, languageCharset);
      return new OkObjectResult(translate);
    }

#UPDATE 2:

I made it, now "/" works, but i have problems with "+". Code

Webapi:

[HttpGet("{phrase}")]
    [Route("getResstring/{phrase}")]
    public IActionResult Get(string phrase)
    {
      phrase = HttpUtility.UrlDecode(phrase);
      var resstring = _translationRepository.GetResstringByPhrase(phrase);
      return new OkObjectResult(resstring);
    }

Angular app:

if( translatedElements[index].getIsTranslated() === false ) {
          this.getResstringByPhrase(encodeURIComponent(translatedElements[index].getValue())).subscribe(async res => {
            const translatedLabel = await this.GetTranslatedByResstring(res, 1045).toPromise()
            if (translatedLabel.getPhrase() !== '') {
              translatedElements[index].setValue(translatedLabel.getPhrase())
            }   
          })
        }

And now the error is (only appears when phrase have "+" inside):

HTTP Error 404.11 – Not Found

The request filtering module is configured to reject the rejection of the cancellation of an alternate double solution.
(sorry for translation from my language)

Solution

You could use asterisk * or double asterisk ** as a prefix to a route parameter:

For example:

[Route("api/[controller]")]
[ApiController]
public class LanguagesController : Controller
{
    [Route("getResstring/{*phrase}")]
    public string GetResstringByPhrase(string phrase)
    {
        return "aa";
    }

}

You could send request url like:https://localhost:44973/api/languages/getResstring/day%20w/o%20break

Be sure your Startup.cs should be like below:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

Result(For test,I just use browser to send request.The browser will encode the url automatically):

enter image description here

Reference:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0#route-template-reference

Update:

Your code has a mistake.Model could not be passed as route value.It could be passed from query string or from body.So you can’t use [Route("{languageCharset}/{resstring}")] to pass the model data to the action.

Then,you need use the specific attribute(e.g [FromQuery],[FromBody],[FromRoute]) to specify the parameter source from.

The difference between route and query string is that:https://localhost:44973/api/languages/getResstring?Id=1,getResstring is route value.?Id=1 is query string.

[Route("api/[controller]")]
[ApiController]
public class LanguagesController : Controller
{
    [Route("getResstring/{*phrase}")]
    public string GetResstringByPhrase(string phrase)
    {
        return "aa";
    }
    [HttpGet]
    [Route("{resstring}")]
    public IActionResult Get([FromRoute]string resstring,[FromQuery]LanguageCharset languageCharset)
    {
        return Ok();
    }
}

Result:

enter image description here

Update 2

For cannot use plus symbol in route,this is an IIS issue:

Please look at the following post:

double escape sequence inside a url : The request filtering module is configured to deny a request that contains a double escape sequence

You need add the following section in your web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration> 
  <system.webServer>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
  </system.webServer>
</configuration>

Result:

enter image description here

Note:

If you do not have web.config file in your project,you could follow the steps to create it:

1.Right-click your project->choose Add->choose New Item:

enter image description here

2.Search config in search bar->choose Web Configuration File:

enter image description here

Leave a Reply

(*) Required, Your email will not be published