我正在使用routes.LowercaseUrls = true;我的MVC 4应用程序,它运行良好.但是,参数也会降低,所以如果我有一个类似的路线
routes.MapRoute(
name: "MyController",
url: "foo/{hash}/{action}",
defaults: new { controller = "MyController", action = "Details" }
);
Run Code Online (Sandbox Code Playgroud)
生成的链接
@Html.ActionLink("my link", "Details", new { hash=ViewBag.MyHash })
Run Code Online (Sandbox Code Playgroud)
也会将{hash}URL 的-part设置为小写,例如,如果ViewBag.MyHash = "aX3F5U"生成的链接将/foo/ax3f5u代替/foo/aX3F5U
有没有办法强制MVC只小写控制器和动作部分?
对于旧版本的MVC,要走的路似乎是实现自定义子类Route,但我不知道如何/在哪里实例化它,因为路由构造函数的签名是完全不同的MapRoute,我希望在那里做一个更简单的方法.
我的[Flags]代码中有一些枚举我想要暴露给JavaScript而不需要复制和粘贴.SignalR似乎通过将URL映射到返回由反射生成的JavaScript存根的Action来为其Hub代理做类似的事情.由于代码是在运行时生成的,因此似乎无法将其包含在Bundles中.
作为替代方案,我在设计时实现了一个T4模板来生成一个js文件:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="EnvDte" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".js" #>
Enums = {
<#
var visualStudio = (Host as IServiceProvider).GetService(typeof(EnvDTE.DTE))
as EnvDTE.DTE;
var project = visualStudio.Solution.FindProjectItem(this.Host.TemplateFile)
.ContainingProject as EnvDTE.Project;
foreach(EnvDTE.ProjectItem item in GetProjectItemsRecursively(project.ProjectItems))
{
if (item.FileCodeModel == null) continue;
foreach(EnvDTE.CodeElement elem in item.FileCodeModel.CodeElements)
{
if (elem.Kind == EnvDTE.vsCMElement.vsCMElementNamespace)
{
foreach (CodeElement innerElement …Run Code Online (Sandbox Code Playgroud) 考虑以下C程序(忽略双重副作用问题):
#define max(a, b) (a>b?a:b)
int main(void){
int max = max(5,6);
return max;
}
Run Code Online (Sandbox Code Playgroud)
GCC预处理器将其转换为:
int main(void){
int max = (5>6?5:6);
return max;
}
Run Code Online (Sandbox Code Playgroud)
这是非常好的,因为你不必担心max和之间的无意碰撞max().在GCC手册说:
类似函数的宏只有在其名称后面带有一对括号时才会展开.如果你只是写下这个名字,那就不管它了
这是标准化还是按照惯例完成的事情?
为模型添加控制器时,生成的操作将如下所示
public ActionResult Edit(int id = 0)
{
Entity entity = db.Entities.Find(id);
if (entity == null)
{
return HttpNotFound();
}
return View(entity);
}
Run Code Online (Sandbox Code Playgroud)
现在在我的情况下,我采用一个字符串id,它可以通过多种方式映射到DB ID,生成几行代码以检索正确的实体.将代码复制并粘贴到每个采用id来检索实体的操作都感觉非常不优雅.
将检索代码放在控制器的私有函数中减少了重复代码的数量,但我仍然留下这个:
var entity = GetEntityById(id);
if (entity == null)
return HttpNotFound();
Run Code Online (Sandbox Code Playgroud)
有没有办法在属性中执行查找并将实体传递给操作?来自python,这可以通过装饰器轻松实现.我设法通过实现一个IOperationBehavior仍然感觉不那么简单的WCF服务做类似的事情.由于通过id检索实体是您经常需要做的事情,我希望除了复制和粘贴代码之外还有其他方法.
理想情况下,它看起来像这样:
[EntityLookup(id => db.Entities.Find(id))]
public ActionResult Edit(Entity entity)
{
return View(entity);
}
Run Code Online (Sandbox Code Playgroud)
其中EntityLookup采用任意函数映射string id,Entity并以HttpNotFound检索到的实体作为参数返回或调用操作.
请考虑以下情形:服务器上的进程用于处理来自网络连接的数据.Twisted使这非常简单,spawnProcess您可以轻松地ProcessTransport在网络端连接您的协议.
但是,我无法确定Twisted如何处理来自网络的数据可用的速度比进程对其标准输入执行读取的速度更快的情况.据我所知,Twisted代码主要使用内部缓冲区(self._buffer或类似的)来存储未使用的数据.这是否意味着来自快速连接(例如,通过本地千兆局域网)的并发请求可能会填满主内存并导致大量交换,使情况更糟?如何防止这种情况?
理想情况下,内部缓冲区将具有上限.据我了解,如果操作系统的缓冲区已满,操作系统的网络代码将自动停止连接/开始丢弃数据包,这会降低客户端的速度.(是的,我知道,网络级别的DoS仍然可以,但这是一个不同的问题).这也是我自己实现的方法:如果内部缓冲区已满,就不要从套接字读取.
在我的情况下,限制最大请求大小也不是一个选项,因为服务应该能够处理任意大小的文件.