我们有一个带有以下Nuget软件包的C#.NET Web Api项目,其中包括其他软件包:
在IIS中,在applicationhost.config文件中为ExtensionlessUrl-Integrated-4.0启用了PUT,PATCH和DELETE谓词。
以下是WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
System.Web.Routing.RouteTable.Routes.Ignore("robots.txt");
System.Web.Routing.RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
// http://weblogs.asp.net/imranbaloch/handling-http-404-error-in-asp-net-web-api
System.Web.Routing.RouteTable.Routes.MapHttpRoute(
name: "Error404",
routeTemplate: "{*url}",
defaults: new { controller = "Error", action = "Handle404" }
);
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
// NOTE: Method below removed and functionality to replace it not working due to bug https://github.com/OData/WebApi/issues/812
//config.EnableCaseInsensitive(caseInsensitive: true);
// http://stackoverflow.com/questions/30987439/elmah-axd-on-webapi-2-2-no-http-resource-was-found
config.Routes.MapHttpRoute(
"AXD", "{resource}.axd/{*pathInfo}", null, null,
new StopRoutingHandler());
// we will use attribute routing
config.MapHttpAttributeRoutes();
// set default page size and total number of rows to return from query
config.AddODataQueryFilter(new EnableQueryAttribute
{
PageSize = ConfigurationWrapper.Singleton.ODataPageSize,
MaxTop = ConfigurationWrapper.Singleton.ODataMaxTop,
MaxExpansionDepth = ConfigurationWrapper.Singleton.ODataMaxExpansionDepth
});
config.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.ReportApiVersions = true;
});
// http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-routing-conventions
// Create the default collection of built-in conventions
IList<IODataRoutingConvention> conventions = ODataRoutingConventions.CreateDefault();
// Insert the custom convention at the start of the collection; caters for ~/entityset/key/navigation/key
conventions.Insert(0, new NavigationIndexRoutingConvention());
config.MapODataServiceRoute(
routeName: "odata",
routePrefix: null,
model: EdmModelBuilder.GetEdmModel(),
pathHandler: new DefaultODataPathHandler(),
routingConventions: conventions,
batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
//config.MapVersionedODataRoutes(
//routeName: "odata",
//routePrefix: null,
//models: EdmModelBuilder.GetEdmModels(config),
//pathHandler: new DefaultODataPathHandler(),
//routingConventions: GetConventions());
// EnableDependencyInjection is required if you want to have OData routes and custom routes together in a controller
config.EnableDependencyInjection();
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null); //new line
config.Formatters.Remove(config.Formatters.XmlFormatter);
// The XML formatter is not well enough supported by OData v4.0 (apparently works with OData v3.0), reverting to JSON only
config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create());
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
/* ReferenceLoopHandling.Ignore: Json.NET will ignore objects in reference loops and not serialize them. The first time an object is encountered
* it will be serialized as usual but if the object is encountered as a child object of itself the serializer will skip serializing it.
*/
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
config.Filters.AddRange(new List<IFilter>
{
new ForfrontAuthenticationAttribute(), // custom
new RateLimitAttribute(), // custom
new RequestAuditAttribute(), // custom
new SuppressResponseCodeSuccessAttribute(), // custom
new ExceptionHandlingAttribute() // custom
});
// http://weblogs.asp.net/imranbaloch/handling-http-404-error-in-asp-net-web-api
config.Services.Replace(typeof(IHttpControllerSelector), new HttpNotFoundAwareDefaultHttpControllerSelector(config));
config.Services.Replace(typeof(IHttpActionSelector), new HttpNotFoundAwareControllerActionSelector());
config.EnsureInitialized();
}
}
我想要调用的控制器操作定义为:
[ApiVersion("1.0")]
[ODataRoutePrefix("MicrosoftDynamicsContactFieldMappings")]
[ControllerName("MicrosoftDynamicsContactFieldMappings")]
public class MicrosoftDynamicsContactFieldMappingsController : ForfrontODataController
{
// DELETE: MicrosoftDynamicsContactFieldMappings(5)
/// <summary>
/// We don't really delete records, but update, user doesn't need to know internal workings.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[AcceptVerbs("DELETE")]
public IHttpActionResult Delete([FromODataUri] int key)
{
// this is not being called
}
}
fiddler中的REST API请求格式为:
DELETE http://dev2.e-shot.local/MicrosoftDynamicsContactFieldMappings(11)
HTTP/1.1
Host: dev2.e-shot.local
User-Agent: Fiddler
Authorization: Token [token value goes here]
Accept-Language: en-GB
当发出DELETE,(PATCH或PUT)请求时,返回404。看起来不考虑OData路由。
希望不必调试OData程序集,任何帮助都非常感激。
谢谢, 瑞克
答案 0 :(得分:1)
更新: 我已经设法通过使用属性路由和避免OData路由约定来使DELETE,PATCH和PUT动词工作。
<div class="three columns bear">
<h3>Matching Tartan Scarf (£2.50)</h3>
<label>
<input type="checkbox" autocomplete="off" name="scarf" id="scarf" value="2.5" />
<img src="Images/Scarft.png">
</label>
<p>Personalise your bear with a matching tartan scarf. It gets cold up here in Scotland, and this is the best way to keep your bear warm.</p>
</div>
<div id="checkoutnecktie"></div>
答案 1 :(得分:0)
就我而言
表名称为:用户
主键字段: IDUser
我必须在EF模型中将 IDUser 列名重命名为 UserId 并运行更新数据库。
在执行以下代码后有效:
[Route("({key})")]
[HttpPatch]
public IActionResult Patch([FromODataUri]int key,
Delta<mUSER> userPatch)
{}