WebApi Controller category, webapicontroller

Source: Internet
Author: User

WebApi Controller category, webapicontroller
Preface

Write this WebApi Controller classification one is to talk about the solution of the Contrller classification, and then talk about the problems and solutions encountered by the way. To be honest, it was very difficult to use WebApi in the project for the first time.

 

Problems and Solutions

1. Multiple Get methods.

The Get request method is the most commonly used, and multiple requests need to be reloaded, which is a good solution. You only need to reload the method according to the parameter. If you are too lazy, you do not need to define any routing rules. You can directly Get? A = XXX & B = XXX.

2. Multiple Post methods.

According to the official WebApi rules, a WebApi cannot contain multiple Post requests. So far, I have not found a method similar to Get reload to handle Post reloads, later, I found someone suggested using Action directly.

Name differentiation (eg. InsertPerson InsertProduct), and then add the HttpPost attribute, which is called directly at the front-end, so I will consider if this is the caseViolating Restful design ideasWhat about it?

3,When a Delete request is encountered, the call to the Delete interface is not successfully called.

At first, I defined the Delete interface for the front-end call (ajax sends the delete request), always reported 405, And then I checked it and said it needed Web. config is used to enable iis delete and PUT requests. I tried several methods and finally failed to handle them. However, I switched to POST requests. PUT requests are useless at all. In the group, I asked if they were originally called in cs using HttpClient.

4. Multiple Post parameters.

The FromBody label is officially recommended, and multiple parameters are encapsulated with Dto. The custom Post parameter binding class inherits HttpParameterBinding. Register GlobalConfiguration. Configuration. ParameterBindingRules. Insert (0, SimplePostVariableParameterBinding. HookupParameterBinding) in Application_Start );

 

Controller category

The Controller classification mainly aims to solve the problem that after the project is too large, the Controller only has a level-1 cataloguing, the project structure will be very messy, and there will be problems that the ApiController file name cannot be solved, when we mention the Controller classification, we will first think of the Area, but in actual application, you will find that it is really tailored for MVC, without mentioning WebApi considerations, for example, when you create an Area, the folder automatically creates controllers, models, and views. SoSolutionIt is to create the Controller cataloguing according to the business logic of the project. The most important thing is to customize the Controller.Controller SelectLet the WebApi framework find the file structure you have defined and ApiController [with code later ].

 

1. This is the Controller structure in my Demo. It contains a level-1 cataloguing and level-2 cataloguing (how does it look like the structure is much clearer ?)

 

 

2. I will summarize the URLs used into a table.

Controller name Namespace Url
AdviseController MvcApplication4.Controllers. ContractUs /Apix/ContactUs/Advise
ProductController MvcApplication4.Controllers. ContractUs /Apix/ContactUs/Product
FinancialController MvcApplication4.Controllers. Products. Enterprise /Apixx/Products/Enterprise/Financial
OfficeController MvcApplication4.Controllers. Products. Enterprise /Apixx/Products/Enterprise/Office
PuzController MvcApplication4.Controllers. Products. Game /Apixx/Products/Game/Puz
RpzController MvcApplication4.Controllers. Products. Game /Apixx/Products/Game/Rpg

The url contains the prefix apix and apixx. Refer to the writing method of a friend in the blog community. In addition, I found that it would not work if the prefix in the first-level and second-level cataloguing is the same, no Controller was selected to handle this request will be reported,Therefore, you need to specify different prefixes based on your cataloguing structure.The url is followed by the Area and Category rules.

 

3. After the Controller catalog structure is created, the routing rules are created (important)

Specify your API prefix apix and apixx

Config. routes. mapHttpRoute (name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new {id = RouteParameter. optional}); // only the first-level cataloguing config. routes. mapHttpRoute (name: "AreaApi", routeTemplate: "apix/{area}/{controller}/{id}", defaults: new {id = RouteParameter. optional}); // contains the level-2 cataloguing config. routes. mapHttpRoute (name: "AreaCategoryApi", routeTemplate: "apix/{area}/{category}/{controller}/{id}", defaults: new {id = RouteParameter. optional });

 

4. After specifying a routing rule, what if WebApi knows your interface? The custom Controller Selector inherits from DefaultHttpControllerSelector. By the way, do not forget to register it in Application_Start () after creating the custom Controller Selector. Otherwise, it is invalid:

GlobalConfiguration. Configuration. Services. Replace (typeof (IHttpControllerSelector), new ClassifiedHttpControllerSelector (GlobalConfiguration. Configuration ));

private const string AREA_ROUTE_VARIABLE_NAME = "area";        private const string CATEGORY_ROUTE_VARIABLE_NAME = "category";        private const string THE_FIX_CONTROLLER_FOLDER_NAME = "Controllers";        private readonly HttpConfiguration m_configuration;        private readonly Lazy<ConcurrentDictionary<string, Type>> m_apiControllerTypes;        public ClassifiedHttpControllerSelector(HttpConfiguration configuration)            : base(configuration)        {            m_configuration = configuration;            m_apiControllerTypes = new Lazy<ConcurrentDictionary<string, Type>>(GetAllControllerTypes);        }        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)        {            return GetApiController(request);        }        private static string GetRouteValueByName(HttpRequestMessage request, string strRouteName)        {            IHttpRouteData data = request.GetRouteData();            if (data.Values.ContainsKey(strRouteName))            {                return data.Values[strRouteName] as string;            }            return null;        }        private static ConcurrentDictionary<string, Type> GetAllControllerTypes()        {            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();            Dictionary<string, Type> types = assemblies.SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && t.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase) && typeof(IHttpController).IsAssignableFrom(t))).ToDictionary(t => t.FullName, t => t);            return new ConcurrentDictionary<string, Type>(types);        }        private HttpControllerDescriptor GetApiController(HttpRequestMessage request)        {            string strAreaName = GetRouteValueByName(request, AREA_ROUTE_VARIABLE_NAME);            string strCategoryName = GetRouteValueByName(request, CATEGORY_ROUTE_VARIABLE_NAME);            string strControllerName = GetControllerName(request);            Type type;            try            {                type = GetControllerType(strAreaName, strCategoryName, strControllerName);            }            catch (Exception)            {                return null;            }            return new HttpControllerDescriptor(m_configuration, strControllerName, type);        }        private Type GetControllerType(string areaName, string categoryName, string controllerName)        {            IEnumerable<KeyValuePair<string, Type>> query = m_apiControllerTypes.Value.AsEnumerable();            string strControllerSearchingName;            if (string.IsNullOrEmpty(areaName))            {                strControllerSearchingName = THE_FIX_CONTROLLER_FOLDER_NAME + "." + controllerName;            }            else            {                if (string.IsNullOrEmpty(categoryName))                {                    strControllerSearchingName = THE_FIX_CONTROLLER_FOLDER_NAME + "." + areaName + "." + controllerName;                }                else                {                    strControllerSearchingName = THE_FIX_CONTROLLER_FOLDER_NAME + "." + areaName + "." + categoryName + "." + controllerName;                }            }            return query.Where(x => x.Key.IndexOf(strControllerSearchingName, StringComparison.OrdinalIgnoreCase) != -1).Select(x => x.Value).Single();        }
Summary

After finding the solution, the next step is to reconstruct the project. We still want to solve the Delete and Put requests. Please give us some advice. Code download http://pan.baidu.com/s/1bnHQItx

 

References

1. http://www.cnblogs.com/guogangj/archive/2013/03/11/2950084.html

2. http://blogs.infosupport.com/asp-net-mvc-4-rc-getting-webapi-and-areas-to-play-nicely/

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.