Search code examples
c#asp.net.netasp.net-web-apiasp.net-web-api-routing

RoutePrefix in web api


I use .net framework 4.0 and web api 1.

I need to use attribute RoutePrefix, which is in web api 2.

Is there analog in first web api?

In Web Api 2:

[RoutePrefix("api/file")]
public class FileController : ApiController
{
 ...

My Api Controller:

public class FileController : ApiController
{
    private IFileManager fileManager;

    public FileController()
        : this(new LocalFileManager(HttpRuntime.AppDomainAppPath + @"\Album"))
    {
    }

    public FileController(IFileManager fileManager)
    {
        this.fileManager = fileManager;
    }

    // GET: api/Photo
    [HttpGet]
    public async Task<HttpResponseMessage> Get()
    {
        var results = await fileManager.Get();
        return Request.CreateResponse(HttpStatusCode.OK, new { photos = results });// (new { photos = results });
    }

    // POST: api/Photo
    [HttpPost]
    public async Task<HttpResponseMessage> Post()
    {
        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent("form-data"))
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest, "Unsupported media type");// BadRequest("Unsupported media type");
        }

        try
        {
            var photos = await fileManager.Add(Request);
            return Request.CreateResponse(HttpStatusCode.OK, new { Message = "Photos uploaded ok", Photos = photos });// Ok(new { Message = "Photos uploaded ok", Photos = photos });
        }
        catch (Exception ex)
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest, ex.GetBaseException().Message);// BadRequest(ex.GetBaseException().Message);
        }

    }

    // DELETE: api/Photo/5
    [HttpDelete]
    [ActionName("{fileName}")]
    public async Task<HttpResponseMessage> Delete(string fileName)
    {
        if (!this.fileManager.FileExists(fileName))
        {
            return Request.CreateResponse(HttpStatusCode.NotFound);// NotFound();
        }

        var result = await this.fileManager.Delete(fileName);

        if (result.Successful)
        {
            return Request.CreateResponse(HttpStatusCode.OK, new { message = result.Message });// Ok(new { message = result.Message });
        }
        else
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest, result.Message);// BadRequest(result.Message);
        }
    }
}

My WebApiConfig:

public static class WebApiConfig
{
    //public static JsonSerializerSettings JsonSerializerSettings { get; private set; }
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Routes.MapHttpRoute(
            name: "FileApi",
            routeTemplate: "api/file/{action}/{fileName}",
            defaults: new { controller = "File", action = "Get", id = RouteParameter.Optional }
        );
    }
}

My angular factory:

function fileManagerClient($resource, $http) {
    return $resource("api/file/:fileName",
            { fileName: "@fileName" },
            {
                'query': { method: 'GET' },
                'save': { method: 'POST', transformRequest: angular.identity, headers: { 'Content-Type': undefined } },
                'remove': { method: 'DELETE', url: 'api/file/:fileName', params: { name: '@fileName' } }
            });

What i need to change to fix it?


Solution

  • In WebApiConfig which Route I need to add to get the FileController by api/file?

    the generic convention-based default route with api/{controller} should work. You could still create one specific to file controller if you want to target that controller.

    public static class WebApiConfig {
        public static void Register(HttpConfiguration config) {
    
            // Convention-based routing.
    
            //GET api/file
            //POST api/file
            //DELETE api/file/somefilename
            config.Routes.MapHttpRoute(
                name: "FileApi",
                routeTemplate: "api/file/{fileName}",
                defaults: new { controller = "File", fileName = RouteParameter.Optional }
            );
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
    

    The order of registering the routes in the route table is important as first matched route wins. Register more specific routes first before more general routes to avoid false matches.