рд▓реЗрдЦ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдПрдХ рдореМрдЬреВрджрд╛ рдХреНрд▓рд╛рд╕рд┐рдХ ASP.NET рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рдПрдХ RESTful рдПрдкреАрдЖрдИ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред
MVC рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЕрдзрд┐рдХрддрдо рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВред
рд╣рдо рдХрд┐рди рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ1. System.Web.Routingред
MyTite.ru/rest/client/0 рдЬреИрд╕реЗ рд▓рд┐рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рд░реВрдЯрдЯреЗрдмрд▓ рдФрд░
IRouteHandler2. System.Web.Mvcред
DefaultModelBinder рдореЙрдбрд▓ рдХреЗ рдЕрдиреБрд░реЛрдз рд╕реЗ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП
3. рдкреНрд░рдгрд╛рд▓реАред
IHttpHandler рдХреЛ CRUD рд╕рдВрдЪрд╛рд▓рди рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рдХрд╛рд░реНрдп рд╕рд┐рджреНрдзрд╛рдВрддрд░реВрдЯрдЯреЗрдмрд▓ рдореЗрдВ рд╣рдо рд░реВрдЯ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЙрд╕ рдЕрдиреБрд░реЛрдз рдХреЛ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдореЗрдВ HttpHandler рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╣рдо рджреЛ рд░реВрдЯ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░рддреЗ рд╣реИрдВ - рд╕реАрдЖрд░рдпреВрдбреА рдСрдкрд░реЗрд╢рдВрд╕ рдХреЗ рд▓рд┐рдП рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░реНрд╕ рд╕рд░реНрдЪ рдСрдкрд░реЗрд╢рдВрд╕ рдХреЗ рд▓рд┐рдПред
HttpHandler рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐ рдФрд░ рдкрд╛рд░рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╡рд╛рдВрдЫрд┐рдд рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИред
рдпрджрд┐ рдпрд╣ рдПрдХ рдЕрдиреБрд░реЛрдз рд╣реИ рдФрд░ рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рдореМрдЬреВрдж рд╣реИ, рддреЛ рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдЦреЛрдЬ рдСрдкрд░реЗрд╢рди рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрджрд┐ рдпрд╣ рдПрдХ рд▓реЗрдЦрди рдСрдкрд░реЗрд╢рди (рдХреНрд░рд┐рдПрдЯ, рдЕрдкрдбреЗрдЯ, рдбрд┐рд▓реАрдЯ) рд╣реИ, рддреЛ DefaultModelBinder рд╡рдВрд╢рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд╛рдВрдЫрд┐рдд рдореЙрдбрд▓ рдмрдирд╛рдиреЗ рдпрд╛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдиреБрд░реЛрдз рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдЙрд╕ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред
рд░реАрдб рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди, рдпрджрд┐ рдЖрдИрдбреА рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдореЙрдбрд▓ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдИрдбреА рдкрд╛рд╕ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рддреЛ рдореЙрдбрд▓ рдХрд╛ рдкреВрд░рд╛ рд╕рдВрдЧреНрд░рд╣ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИред
рдореЙрдбрд▓ рдХреЛ JSON рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рдЪрд░рдг рд╣реИред
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ 30 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдХреИрд╢рд┐рдВрдЧ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреА рд╣реИред
рдореИрдВрдиреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рддрд╛рдХрд┐ рдХреЛрдб рдХреЛ рдЕрд╡реНрдпрд╡рд╕реНрдерд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдХрд┐рд╕реА рд╕рдорд╛рдзрд╛рди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╕рдордп, рджреЛ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рдЙрддреНрдкрдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИрдВ:
1. 404 рддреНрд░реБрдЯрд┐ - IIS рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдЬрд╛рдВрдЪ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдХреЗ рдЗрд▓рд╛рдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
(
рдпрд╣рд╛рдВ рджреЗрдЦреЗрдВ рдпрд╛ рдиреАрдЪреЗ web.config рд╕реЗрдЯрд┐рдВрдЧреНрд╕)
2. рд╕рддреНрд░ рдХреА рд╡рд╕реНрддреБ рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реИ - рдЗрд╕рдХрд╛ рдЙрдкрдЪрд╛рд░ рд╕рддреНрд░ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
(
рдпрд╣рд╛рдВ рджреЗрдЦреЗрдВ рдпрд╛ рдиреАрдЪреЗ web.config рд╕реЗрдЯрд┐рдВрдЧреНрд╕)
рдЖрд╡реЗрджрди рд╕реНрд░реЛрдд
рдпрд╣рд╛рдВ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ
рд╣реИрдВрдЧреНрд░рд╛рд╣рдХ рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрджрд╛рд╣рд░рдгрдХреНрд▓рд╛рд╕ ClientRestHttpHandlerpublic class ClientRestHttpHandler : RestHttpHandler<Client, ClientModelBinder> { protected override IEnumerable<Client> GetAll() { return ClientService.GetAll(); } protected override Client GetBy(int id) { return ClientService.GetById(id); } protected override IEnumerable<Client> GetBy(NameValueCollection query) { var result = ClientService.GetAll(); var contains = query["contains"]; if (contains != null) { result = from item in result where item.FirstName.Contains(contains) || item.LastName.Contains(contains) select item; } return result; } protected override void Create(Client entity) { ClientService.Create(entity); } protected override void Update(Client entity) { ClientService.Update(entity); } protected override void Delete(Client entity) { ClientService.Delete(entity); } protected override object ToJson(Client entity) { return new { entity.Id, entity.FirstName, entity.LastName }; } }
рдХреНрд▓рд╛рд╕ ClientModelBinder public class ClientModelBinder : DefaultModelBinder { protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, System.Type modelType) { var value = bindingContext.ValueProvider.GetValue("id"); if (value == null) return ClientService.New(); var result = (int)value.ConvertTo(typeof(int)); return ClientService.GetById(result); } }
Global.asax рдореЗрдВ рдирд╛рдо void Application_Start(object sender, EventArgs e) { RestRouteHandler<ClientRestHttpHandler>.Register("client", "clients"); }
рд╡реЗрдм рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ <configuration> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <remove name="Session" /> <add name="Session" type="System.Web.SessionState.SessionStateModule"/> </modules> <handlers> <add name="WildCard" path="*" verb="*" resourceType="Unspecified" /> </handlers> </system.webServer> </configuration>
рдпрд╣реА рд╣реИ, рдХреНрд▓рд╛рдЗрдВрдЯ рдореЙрдбрд▓ рд╣рдорд╛рд░реА рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ REST API рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реИред
рдмреЗрд╕ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕реНрд░реЛрдд рд░реЗрд╕реНрдЯрд╣реЗрдЯрдлреИрдВрдбрд▓рд░ рдФрд░ рд░реЗрд╕реНрдЯреЗрд░рдЯрд╣реИрдВрдбрд▓рд░ public abstract class RestHttpHandler : IHttpHandler, IReadOnlySessionState { public const string ParamKeyId = "id"; public const string ParamKeyQuery = "query";
public abstract class RestHttpHandler<T, TBinder> : RestHttpHandler where T : class where TBinder : DefaultModelBinder, new() {
public class RestRouteHandler<T> : IRouteHandler where T : RestHttpHandler, new() { IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) { return new T() { RouteData = requestContext.RouteData }; } public static void Register(string name, string pluralName) { RouteTable.Routes.Add( name, new Route( string.Format( "rest/{0}/{{{1}}}", name, RestHttpHandler.ParamKeyId ), new RestRouteHandler<T>() ) { Defaults = new RouteValueDictionary { { RestHttpHandler.ParamKeyId, null } }, Constraints = new RouteValueDictionary { { RestHttpHandler.ParamKeyId, "\\d*" } } } ); RouteTable.Routes.Add( pluralName, new Route( string.Format( "rest/{0}/{{*{1}}}", pluralName, RestHttpHandler.ParamKeyQuery ), new RestRouteHandler<T>()) { Defaults = new RouteValueDictionary { { RestHttpHandler.ParamKeyQuery, "" } } } ); } }
рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рдЕрдиреБрднрд╡ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред