0

How can i edit all request url and data model before routing in C# web api?

I have a method to change number from persian to english

public static string toEnglishNumber(string input)
    {
        string[] persian = new string[10] { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };

        for (int j = 0; j < persian.Length; j++)
            input = input.Replace(persian[j], j.ToString());

        return input;
    }

but i have to run this method for all of my controller and value. I want to set a filter on url and it's form data before it run any of controllers.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Mohammad Reza Mrg
  • 1,552
  • 15
  • 30
  • @Fildor (Persian)it means the numbers in the Iranian language – Anas Alweish Oct 25 '18 at 12:06
  • @Mohammad: Somebody voted "unclear what you are asking". Could you explain a little more? You get request urls that contain persian numbers? Is that it? Can you add some examples? – Fildor Oct 25 '18 at 12:15
  • You probably need a custom type converter or a model binder, see [Parameter Binding in ASP.NET Web API](https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api#type-converters) and also [How to bind to custom objects in action signatures in MVC/WebAPI](https://blogs.msdn.microsoft.com/jmstall/2012/04/20/how-to-bind-to-custom-objects-in-action-signatures-in-mvcwebapi/) – Rui Jarimba Oct 25 '18 at 12:23
  • Your request make perfect sense. Code simply uses the index of the array with to convert to Arabic numerals. I think you mean that you need to modify the RESPONSE (not REQUEST). I would create a class that inherits the WebRequest and then do the modification in the class. See : https://stackoverflow.com/questions/400565/is-there-any-way-to-inherit-a-class-without-constructors-in-net – jdweng Oct 25 '18 at 12:29
  • For example: http://myhost.com/api/product/٢۴۱۵ – Mohammad Reza Mrg Oct 27 '18 at 05:57

2 Answers2

0

if I understand your question the right way, a DelegatingHandler is what you need. It could be like this:

public class RequestHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {

        Console.WriteLine(request.RequestUri);
        request.RequestUri = new Uri(toEnglishNumber(request.RequestUri.ToString()));
        Console.WriteLine(request.RequestUri);

        return base.SendAsync(request, cancellationToken);
    }

    public static string toEnglishNumber(string input)
    {
        string[] persian = new string[10] { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };

        for (int j = 0; j < persian.Length; j++)
            input = input.Replace(persian[j], j.ToString());

        return input;
    }
}

Every request runs first in the handler where you can do your staff. You need to register it globally:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {            
        config.MessageHandlers.Add(new RequestHandler());

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

And for a simple test a controller:

public class TestController : ApiController
{
    public IHttpActionResult Get(int number)
    {
        return this.Ok($"Hello World {number}.");
    }
}

And it is possible to do this:

enter image description here

As further reference, see the web api poster: https://www.asp.net/media/4071077/aspnet-web-api-poster.pdf

Happy coding!

P. Grote
  • 249
  • 1
  • 2
  • 13
0

Not sure if it's a good solution but it seems work:

Add a custom filter

public class MyUrlDataFilterAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var dict = actionContext.ControllerContext.RequestContext.RouteData.Values;
        List<string> keyList = new List<string>();
        foreach (string key in dict.Keys) keyList.Add(key);
        foreach (string key in keyList)
        {
            string s = dict[key] as string;
            if (s != null) dict[key] = toEnglishNumber(s);
        }
    }
}

and config.Filters.Add(new MyUrlDataFilterAttribute()); in WebApiConfig.Register(HttpConfiguration config)

skyoxZ
  • 362
  • 1
  • 3
  • 10