1

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)

Obyi
  • 617
  • 1
  • 6
  • 13

2 Answers2

4

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://learn.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

Rena
  • 30,832
  • 6
  • 37
  • 72
  • Thanks, it looks like it gonna work, but look at my updated question. I added * to resstring, but in my attempt to do this, when i debugging i reciving under resstring part of path, in this example it's looke like this : phrase="getResstring/day w/o break" . I want to get only phrase="day w/o break". If i put it in route, not httpget, i recive "The value 'getResstring' is not valid." – Obyi Mar 16 '21 at 06:46
  • 1
    Hi,why do you add multiple route?In your scenario,it seems you need `[Route("getResstring/{*phrase}")]`. – Rena Mar 16 '21 at 06:48
  • Sorry, but i wrote it in edit. If i use [Route("getResstring/{*phrase}")], i reciving "The value 'getResstring' is not valid. It don't even get into this function, so my breakpoint not helps in this situation – Obyi Mar 16 '21 at 06:49
  • 1
    Where did you get this error message?Be sure remove `[HttpGet("{*phrase}")]`. – Rena Mar 16 '21 at 06:53
  • 1
    You used `[Route("getResstring/{phrase}")]` in your edit not `[Route("getResstring/{*phrase}")]`.Please be carefull. – Rena Mar 16 '21 at 06:58
  • Still: "The value 'getResstring' is not valid." – Obyi Mar 16 '21 at 07:00
  • 1
    Could you please share where did you get this error?If you do not hit the endpoints,it only return 404 Http status error.Please learn to set breakpoints to debug the code. – Rena Mar 16 '21 at 07:03
  • I did it in next answer – Obyi Mar 16 '21 at 07:13
0

If i type: https://localhost:44397/api/translation/getResstring/polish

Then i recive:

{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|cfc7e08b-41bcf96eadd38d17.","errors":{"languageCharset":["The value 'getResstring' is not valid."]}}

If i type: https://localhost:44397/api/translation/getResstring/day%20w/o%20break

Then i just recive: Page not found

When i remove all *, firt attempt working, second giving the same

Obyi
  • 617
  • 1
  • 6
  • 13
  • What is your version of asp.net core? – Rena Mar 16 '21 at 07:19
  • 1
    And please edit the thread and share your detailed code.Not sure what is your `languageCharset`.Did you do any other things in your action?Please check your project,there is no same endpoint. – Rena Mar 16 '21 at 07:22
  • 1
    Check your action in your project,if it needs a parameter contains `languageCharset` property. – Rena Mar 16 '21 at 07:25
  • 1
    I guess it may caused by this line:`_translationRepository.GetResstringByPhrase`.Be sure you only have `[Route("getResstring/{*phrase}")]` in your action.Do not use any of `[HttpGet("{*phrase}")]` or `[Route("getResstring/{phrase}")]`. – Rena Mar 16 '21 at 07:29
  • I fixed, sorry about that but i pasted wrong method in angular side, now it's fixed in my question. Yes, atm i have only [Route("getResstring/{*phrase}")] and it still doesnt work – Obyi Mar 16 '21 at 07:31
  • 1
    Only if you share the detailed code then we will resolve your issue.Otherwise,it always work in my prokect.I suggest that you could create a new repo which could reproduce your issue. – Rena Mar 16 '21 at 07:34
  • But i posted full path to api, it works until i add "/" to the searched string, so the problem is with it, if you want how i making request, it look like it in postman: https://localhost:44397/api/translation/getResstring/polski and it shoud return string, but after added * it not works – Obyi Mar 16 '21 at 07:36
  • 1
    Please answer my previous questions.You never answer my question and only said does not work.I need ask again.What is your version of asp.net core?And your error message have a field named `languageCharset`.That is to say,you may have an action which contains a parameter and it has model validation.Please check carefully.All of these you need share with us.Also,what is your Startup.cs.How do you configure the route template(what I did I have provided in my answer)? – Rena Mar 16 '21 at 07:42
  • Ok, now i know the answer. It not used in this request, but used in other request in api where route looks like this: [Route("{languageCharset}/{resstring}")] It looks like it not going to my getResstring api methot, but to the other because of * char inside path – Obyi Mar 16 '21 at 08:00
  • 1
    Yes.That is what I said in my previous comment.Remember to avoid using conflict endpoint.Then using what my answer did.It will work well as mine.If my answer helped you,remember to accept as answer. – Rena Mar 16 '21 at 08:03
  • Ok, i added startup.cs (important part) to question – Obyi Mar 16 '21 at 08:12
  • You said you have found the answer.So you need share the conflict action:`but used in other request in api where route looks like this: [Route("{languageCharset}/{resstring}")]`. – Rena Mar 16 '21 at 08:16
  • Done in question – Obyi Mar 16 '21 at 08:25
  • Any ideas how to fix it? – Obyi Mar 16 '21 at 08:35
  • 1
    Please give me some minutes. – Rena Mar 16 '21 at 08:36
  • Ok, im waiting. – Obyi Mar 16 '21 at 08:37
  • 1
    Hi @Obyi,Your code has a mistake.Model could not be passed from 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.Check my updated answer.And check my updated gif.It will help you understand the code. – Rena Mar 16 '21 at 09:26
  • @Rena Hey, check my updated answer #Update 2. I figured out how to fix problem with "/", but now i have issue "+" – Obyi Mar 16 '21 at 10:51
  • 1
    Hi @Obyi,check my Update 2 answer.Actually it is a new issue.The previous issue I have helped you resolve it.Remember to accept as answer. – Rena Mar 17 '21 at 01:44