我遇到的情况是.Net WebApi项目的默认方式不适用于我的团队。我们每隔几周就会产生一个新的“版本”代码。例如,我们可能为公司A构建一个具有或多或少相同后端代码的站点,但连接字符串除外。大多数客户端代码都是相同的,但有些将是自定义的,index.cshtml将是自定义的。
作为创建干净描述的第一步,共享代码可以进入自己的存储库,自定义前端代码可以转到每个客户端的一个仓库,我将前端拆分为自己的项目并拆除以前是WebApi和客户端代码的项目只包含WebApi代码而没有必要。为此,我从一个空项目开始,选中了WebApi复选框并开始添加内容,直到项目至少进行编译。
即使我们还没有使用VS 2013和.Net 4.5,我觉得基于gulp的解决方案现在不适合我们(我研究了一个多星期,所以请< / strong>在回答时牢记这一点。
我遇到的问题是我认为我正在构建的HTTPConfiguration未被应用程序使用。症状是它似乎没有认识到最自定义的路由定义,我认为它不使用JSON合同解析器。
我尝试安装RouteDebugger,但它似乎取决于某些Nuget软件包的旧版本,因此无法安装。
public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureOAuth(app); var config = new HttpConfiguration(); var container = new Container(); container.RegisterSingle(); config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); app.UseCors(CorsOptions.AllowAll); app.UseWebApi(config); WebApiConfig.Register(config); config.EnsureInitialized(); } }
public static class WebApiConfig { public static string UrlPrefix { get { return ""; } } public static string UrlPrefixRelative { get { return ""; } } public static void Register(HttpConfiguration config) { config.EnableCors(); config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "SignOnApi", routeTemplate: UrlPrefix + "{controller}/{language}", defaults: new { id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "SessionRoute", routeTemplate: UrlPrefix + "{controller}/{action}/{userId}", defaults: new {userId = RouteParameter.Optional} ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: UrlPrefix + "{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); var jsonFormatter = config.Formatters.OfType().First(); jsonFormatter.UseDataContractJsonSerializer = true; jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } }
我已经验证所有这些代码确实执行了。
如果我遗漏了其他信息,请告诉我 - 这已经是一个很长的问题了。
当我从浏览器调用一个使用get方法的服务时,我得到了
<Error><Message>An error has occurred.</Message><ExceptionMessage>Type 'VJTNext.Models.Templates.SituationalJudgement' with data contract name 'SituationalJudgement:http://schemas.datacontract.org/2004/07/VJTNext.Models.Templates' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.</ExceptionMessage><ExceptionType>System.Runtime.Serialization.SerializationException</ExceptionType><StackTrace> at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteArrayOfanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteTemplateSectionToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteArrayOfTemplateSectionToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteTemplateMasterToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__13.MoveNext()</StackTrace></Error>
我知道它可能没有使用JSON解析器,因为我直接从浏览器调用它,但我的理解是XML解析器应该同样宽容。
当AngularJS客户端在不同的服务上调用post方法时,它会返回
"<Error>No HTTP resource was found that matches the request URI 'http:\/\/localhost:58324\/api \/Account\/RegisterUser'.<\/Message><MessageDetail>No action was found on the controller 'Account' that matches the request.<\/MessageDetail><\/Error>"
当我拆分项目时,我将Web Api部件设置为在客户端代码的虚拟子目录中运行(发布到真实服务器上的物理子目录)。正在执行某事但未使用数据合同的控制器没有RoutePrefix元数据,但其他人没有。因此,从前缀中删除“api /”会修复它,因为这些服务现在实际上位于该目录中,而不是在该路径上。
现在,要让数据合同正常运转了。