我想全局拦截某些$http
错误情况,阻止控制器自己处理错误.我认为HTTP拦截器是我需要的,但我不知道如何让我的控制器也处理错误.
我有一个像这样的控制器:
function HomeController($location, $http) {
activate();
function activate() {
$http.get('non-existent-location')
.then(function activateOk(response) {
alert('Everything is ok');
})
.catch(function activateError(error) {
alert('An error happened');
});
}
}
Run Code Online (Sandbox Code Playgroud)
像这样的HTTP拦截器:
function HttpInterceptor($q, $location) {
var service = {
responseError: responseError
};
return service;
function responseError(rejection) {
if (rejection.status === 404) {
$location.path('/error');
}
return $q.reject(rejection);
}
}
Run Code Online (Sandbox Code Playgroud)
这与浏览器重定向到'/ error'路径一样有效.但在承诺抓HomeController
的也执行了,我不希望这样.
我知道我可以编码HomeController
,它忽略了404错误,但这是不可维护的.假设我修改HttpInterceptor
为也处理500个错误,然后我必须HomeController
再次修改(以及可能已经添加的任何其他控制器使用$http
).有更优雅的解决方案吗?
假设我有两个集合,每个集合的值彼此独立,但每个集合彼此相关.他们是photos
和users
.用户和照片之间存在一对多的关系.
非规范化数据的一个例子:
users:
{
"id": "AABC",
"name": "Donna Smith"
}
photos:
{
"id": "FAD4",
"description": "cute dog",
"user_id": "AABC", // This is the relationship
"user_name": "Donna Smith" // This is the denormalized value from the "users" collection
}
Run Code Online (Sandbox Code Playgroud)
photos
当用户"AABC"将名称从"Donna Smith"更改为"Donna Chang"时,如何确保与集合中的文档保持一致?
作为非交易性的,我理解一致性将是最终的.
在更改用户"AABC"以更新user_id ="AABC"的所有照片后,简单(天真)实现可能会触发后台作业.在单次更新的情况下,这将很好.但这是一个多用户环境,并且会同时在各个方向上进行更新.例如,如果在照片的背景更新中途将"Donna Smith"更改为"Donna Chang",用户"AABC"的名称将更改为"Donna Smith"?
在线搜索,我看到很多关于如何建模非规范化数据的讨论.但是关于如何维护它的任何讨论似乎都被轻视为"你还需要更新所有相关记录".在这种情况下,是否有任何NoSQL系统为您提供繁重的工作?任何框架或实用程序?
我已经阅读了Thomas Wanschik关于"物化视图"主题的精彩博客文章以及这个场景的背景更新.但我担心:
我有一个带有简单Web服务的ASP.NET 4.0 WebForms页面WebMethod
.此方法用作异步/ TPL代码的同步包装器.我面临的问题是,内部Task
有时会有一个null SynchronizationContext
(我的偏好),但有时会有一个同步上下文System.Web.LegacyAspNetSynchronizationContext
.在我提供的示例中,这并不会导致问题,但在我的实际开发场景中可能会导致死锁.
对服务的第一次调用似乎总是使用空同步上下文运行,接下来的几个也可能.但是一些快速激活的请求会开始弹出ASP.NET同步上下文.
[WebMethod]
public static string MyWebMethod(string name)
{
var rnd = new Random();
int eventId = rnd.Next();
TaskHolder holder = new TaskHolder(eventId);
System.Diagnostics.Debug.WriteLine("Event Id: {0}. Web method thread Id: {1}",
eventId,
Thread.CurrentThread.ManagedThreadId);
var taskResult = Task.Factory.StartNew(
function: () => holder.SampleTask().Result,
creationOptions: TaskCreationOptions.None,
cancellationToken: System.Threading.CancellationToken.None,
scheduler: TaskScheduler.Default)
.Result;
return "Hello " + name + ", result is " + taskResult;
}
Run Code Online (Sandbox Code Playgroud)
存在的定义TaskHolder
:
public class TaskHolder …
Run Code Online (Sandbox Code Playgroud) asp.net synchronizationcontext task-parallel-library webmethod async-await
我在VS2012中有一个Web应用程序项目,我使用"Web部署包"发布.我希望此程序包包含应用程序池设置,特别是创建 IIS应用程序池并将新创建的应用程序分配给它.
我熟悉项目配置为使用IIS实例(不是IIS Express)时可用的"包括此Web项目使用的应用程序池设置"选项,但IIS配置不是项目文件的一部分,因此不是源代码受控.当有人在没有经过精心配置IIS的机器上构建部署包时会发生什么?不理想.
那么,我还可以将AppPool设置添加到我的Web部署包中吗?我知道appPoolConfig提供程序只是IIS7 +,我很好用这个限制.我过去一直反对这个问题,从来没有找到解决方案.18个月后,我们有了一个新的VisualStudio版本和一个新的网络发布管道,是否有新的选项来解决这个问题?或者也许是我第一次解决这个问题时错过了什么?
编辑
好的,我看到以下选项:
MSDeploy.MSDeployProviderOptions
看起来有一些Base64编码的二进制文件?不知道该放什么.appPoolConfig
提供者似乎只想读/写IIS,而不是设置的XML文件.有人知道吗?MyCustomPoolProvider
将appPoolConfig
部分写入清单?这听起来像是一种潜在的痛苦运动,可能会或可能不会起作用.我还需要弄清楚进入的编码MSDeploy.MSDeployProviderOptions
吗?我感觉Web Deploy对于我正在努力实现的目标的根本障碍是它严格依赖于"提供者".预先存在的提供程序主要用于IIS同步,而不是主要开发和发布.碰巧这些提供商中的一些可以通过MSBuild 相对容易地连接,但大多数人坚持从IIS中提取数据,就是这样.
我有一个ASP.NET Web API控制器,我原本认为它将异步操作.控制器设计为第一次请求休眠20秒,但立即为任何后续请求提供服务.所以我预期的时间表是这样的:
相反,在请求1完成之前,没有请求返回.
我可以确认(基于调试输出),入口线程和困线程id是不同的.我故意用来TaskCreationOptions.LongRunning
强制睡眠到一个单独的线程,但是应用程序仍然拒绝服务任何新的请求,直到睡眠结束.
我是否遗漏了有关异步Web API控制器如何工作的基本信息?
public class ValuesController : ApiController
{
private static bool _firstTime = true;
public async Task<string> Get()
{
Debug.WriteLine("Entry thread id: {0}. Sync: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current);
await LongWaitAsync();
return "FOOBAR";
}
private Task LongWaitAsync()
{
return Task.Factory.StartNew(() =>
{
if (_firstTime)
{
_firstTime = false;
Debug.WriteLine("Sleepy thread id: {0}. Sync: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current);
Thread.Sleep(20000);
Debug.WriteLine("Finished sleeping");
}
},
CancellationToken.None,
TaskCreationOptions.LongRunning,
TaskScheduler.Default); …
Run Code Online (Sandbox Code Playgroud) 我有一个包含非压缩文件的安装程序包.
<DirectoryRef Id="INSTALLLOCATION">
<Component Id="LocationConfig">
<File Id="LocationConfigFile"
Source="LooseFile.Config"
DiskId="2"
Vital="no"
Compressed="no" />
</Component>
</DirectoryRef>
Run Code Online (Sandbox Code Playgroud)
此文件松散的目的是在安装之前进行编辑.这可以按预期工作.
我有一个刻录链指定松散文件作为松散文件包含在引导程序旁边.还要注意使用SuppressLooseFilePayloadGeneration
允许手动指定文件作为松散的有效负载.
<Chain>
<MsiPackage SourceFile="MyInstaller.msi"
Visible="yes"
Vital="no"
SuppressLooseFilePayloadGeneration="yes">
<Payload Compressed="no" SourceFile="LooseFile.Config" />
</MsiPackage>
</Chain>
Run Code Online (Sandbox Code Playgroud)
刻录日志如下所示:
[3860:38D8][2013-04-26T16:42:48]e000: Error 0x80091007: Hash mismatch for path: C:\ProgramData\Package Cache\.unverified\payAC32431CF002C09E2F0B537A32ACA259
[3860:38D8][2013-04-26T16:42:48]e000: Error 0x80091007: Failed to verify hash of payload: payAC32431CF002C09E2F0B537A32ACA259
[3860:38D8][2013-04-26T16:42:48]e310: Failed to verify payload: payAC32431CF002C09E2F0B537A32ACA259 at path: C:\ProgramData\Package Cache\.unverified\payAC32431CF002C09E2F0B537A32ACA259, error: 0x80091007. Deleting file.
[3860:38D8][2013-04-26T16:42:48]e000: Error 0x80091007: Failed to cache payload: payAC32431CF002C09E2F0B537A32ACA259
[33FC:3A54][2013-04-26T16:42:48]e314: Failed to cache payload: payAC32431CF002C09E2F0B537A32ACA259 from working …
Run Code Online (Sandbox Code Playgroud) 根据MSDN文章中的指导如何:确定安装了哪些.NET Framework版本我已编写了一个WiX安装程序来检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\Release
注册表项以确定是否已安装.NET 4.5.1,并使用该检测设置先决条件.
我现在遇到的问题是,当安装.NET 4.5.2时,同一个密钥不再是,378675
或者378758
现在是379893
..NET 4.5.2应该是"高度兼容的就地更新",但推荐的版本检查算法不是向后兼容的.
检查以前的版本没有此问题,即使安装了更高版本,2.0,3.0和3.5注册表项仍然存在.如HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Version
仍然存在,即使安装了3.5.
以前,Microsoft推荐的版本检测方法是向前兼容的,但4.5/4.5.1/4.5.2不再是这种情况.那么,我应该做什么呢?我不愿意将379893
(.NET 4.5.2)添加到我检查的注册表值集中,因为当(如果).NET 4.5.3(或其他)发布时,这可能会失败.也许我可以检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\Version
> = 4.5.51641,但根据MSDN,这不是推荐的方法,如果它们发布,例如4.6,它在某种程度上不向后兼容会发生什么?
对于ASP.NET Web API,我一直在研究自己的实现,IHttpControllerActivator
并且想知道何时(或为什么?)使用HttpRequestMessage
扩展方法" RegisterForDispose
".
我看到这样的例子,我可以看到它的相关性,因为IHttpController不继承IDisposable,而IHttpController的实现并不保证它自己的dispose逻辑.
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { var controller = (IHttpController) _kernel.Get(controllerType); request.RegisterForDispose( new Release(()=> _kernel.Release(controller))); return controller; }
但后来我看到这样的事情并开始怀疑:
public IHttpController Create( HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { if (controllerType == typeof(RootController)) { var disposableQuery = new DisposableStatusQuery(); request.RegisterForDispose(disposableQuery); return new RootController(disposableQuery); } return null; }
在这个例子中,RootController在这里没有注册处理,大概是因为它是一个ApiController或MVC控制器? - 因此会自行处理.
DisposableStatusQuery的实例已注册处置,因为它是一个一次性对象,但为什么控制器不能处理实例本身?RootController具有disposableQuery(或者更确切地说,它的接口或抽象基础)的知识,因此会知道它是一次性的.
我什么时候才能真正需要使用HttpRequestMessage.RegisterForDispose?
我有一个ASP.NET IHttpModule实现,旨在重写服务文件的路径.该模块只处理一个事件,PostAuthenticateRequest
如下所示:
void context_PostAuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Request.Path.ToLower().Contains("foobar"))
{
HttpContext.Current.RewritePath("virtdir/image.png");
}
}
Run Code Online (Sandbox Code Playgroud)
路径"virtdir"是应用程序的虚拟目录子级.应用程序本身在典型位置运行:C:\ inetpub\wwwroot\IisModuleCacheTest \虚拟目录"virtdir"映射到C:\ TestVirtDir \
的请求http://myserver/iismodulecachetest/foobar
会如预期,从虚拟目录返回image.png.同样,请求http://myserver/iismodulecachetest/virtdir/image.png
将返回相同的图像文件.
然后我执行以下操作:
http://myserver/iismodulecachetest/foobar
在间隔几秒钟的1到20次重复之后,返回的图像将是过时的副本.
一旦感到不安,服务器将在经过一段未知时间后(从10秒到几分钟)返回当前版本.如果我用步骤1中的URL替换http://myserver/iismodulecachetest/virtdir/image.png
,则问题似乎不会出现.但奇怪的是,在使用"foobar"URL出现问题后,直接URL 也开始返回图像的过时副本.
相关细节:
<caching enabled="false" enableKernelCache="false" />
编辑 - 更多详情:
http://myserver/iismodulecachetest/foobar.png
.context_PostAuthenticateRequest
每次都会触发事件处理程序,并且无论缓存是否卡住,其行为方式都相同.Edit2 - IIS日志: …
我把一起使用的ASP.NET Web API文档管理服务,以及性能的一些担忧.
基于IIS/ASP.NET ImageResizer模块的作者Nathanael Jones撰写的这篇文章,我对服务静态文件的"最佳"性能所需的内容有了一些先入之见.正是这样:
HttpModule
因为它在ASP.NET管道的早期(较少的管道=更优化),并且结果更容易处理这类事情而不是HttpHandler
.Response.WriteFile(filename)
比Response.Write(memBuffer)
memBuffer是内存中的C#缓冲区更好.Context.RewritePath(virtualPath)
)更好Response.WriteFile(filename)
,因为它将使用IIS静态文件处理程序,这是经过优化的.麻烦的是,由于一些奇怪的缓存问题,我仍然无法达到(这里)的底部,我的URL重写技术本身并不表现.
所以现在我想知道更多以Web API为中心的实现,如下所示:
public Task<HttpResponseMessage> DoTheFoo()
{
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
var response = new HttpResponseMessage();
response.Headers.Add("Content-Disposition", "inline; filename=\"" + attachmentFileName + "\"");
response.Headers.Add("content-type", mimeType);
response.Content = new StreamContent(File.OpenRead("somefile.doc"));
return response;
});
}
Run Code Online (Sandbox Code Playgroud)
对于Web API解决方案,这显然会使事情变得更加简洁,因为服务的文件服务部分可以与控制器中的其他操作一起使用,但它的执行和扩展程度如何?我思考的因素:
我无法组建一个服务器场来测试它以获得真实的性能数据,而且我怀疑将小规模测试结果分解会给出任何准确的结果.那些知情人士,我可以期待什么样的差异?我几乎已经准备好放弃URL重写实现,但如果它会给我一个明显的性能影响,我会坚持下去.
asp.net ×3
async-await ×2
iis ×2
.net ×1
angularjs ×1
asp.net-mvc ×1
burn ×1
c# ×1
caching ×1
denormalized ×1
httpmodule ×1
iis-7.5 ×1
msdeploy ×1
nosql ×1
performance ×1
webmethod ×1
wix ×1