我正在构建一个RESTful Web服务.我已经阅读了为每个机制使用HTTP的原则,只要它会占用你,而且大多数时候,就像获取资源一样,它工作得很好.
但是当我需要发布某种新条目时,为了清晰和健壮,无论客户端做什么,我都想提供新条目可能失败的特定验证错误.此外,存在特定错误,例如,用于创建新用户的数据完全有效,但可以采用昵称或电子邮件地址.简单地返回409 Conflict没有详细说明昵称或电子邮件地址的详细信息.
所以解决这个问题不是火箭科学:记录一堆特定的错误代码并返回一个有错误的对象:
{ errors: [4, 8, 42] }
Run Code Online (Sandbox Code Playgroud)
这意味着在请求失败的情况下,我不会返回REST哲学所预期的资源或密钥.类似地,当我返回许多资源时,我必须以某种方式在数组中构造它们.
所以我的问题是:如果我为每个请求标准化一个信封,我是否仍然会提供一个表现良好的RESTful Web服务,例如,总有一个像这样的对象{ errors, isSuccessful, content }?
我之前已经构建了使用它的RPC风格的Web服务,但我不想做一些"几乎是REST"的东西.如果有任何关于REST的意义,我希望尽可能保持良好的行为.
如果答案是"地狱没有",我认为它可能是,我想知道它是否至少正确地解决了验证问题,并且对于这种问题解决可能是一个很好的参考,因为大多数指南我都是我发现只详细的简单案例.
我正在从服务器向客户端发送大量不同的JSON图(我控制它们),它们都包含一个病态案例:大量同类(相同类型)值.因此,例如,部分有效负载如下所示:
[{"LongPropertyName":87, "AnotherVeryLongPropertyName":93,
"BlahBlahBlahBlahBlah": 78},
{"LongPropertyName":97, "AnotherVeryLongPropertyName":43,
"BlahBlahBlahBlahBlah": 578},
{"LongPropertyName":92, "AnotherVeryLongPropertyName":-3,
"BlahBlahBlahBlahBlah": 817}, ...
Run Code Online (Sandbox Code Playgroud)
我添加了一些格式,但正如你所看到的,从霍夫曼编码的角度来看,这是荒谬的,即应该有效地表达常见的东西.
所以,既然我控制了反序列化和序列化结束,我想实现一个转换,其中:
[{"Key1":87,"Key2":99},{"Key1":42,"Key2":-8}]
Run Code Online (Sandbox Code Playgroud)
变成了这样的东西:
[["$","Key1","Key2"],[87,99],[42,-8]]
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样,即使只有两个物体,它也会更紧凑.
我在哪里挂钩到Json.NET来进行这种转换?我想自动为尽可能多的对象执行此操作.我找到了ContractResolvers,但我不确定它们是否在我想要的阶段发生 - 我不确定如何使用它的方法将JSON对象/字典转换为数组.
或者,如果已经为Json.NET实现了类似的东西,我想要使用它.但是我并不担心我想要做出的那种改变(见上文),就在我将Json.NET挂钩以实现它的地方.
(我试过gzipping它.它工作正常并在70%和95%之间剃掉,但它仍然需要输出完整的JSON文本并完成所有压缩/解压缩.这个问题是:我如何输出更紧凑的从一开始的数据形式?)
更新:你这样做的方式是JsonConverter.我已经写过几篇,但出于某种原因,我认为他们会发生冲突.
我最终得到的是Brian Rogers的基础以及一些更改,以嵌入/展平任何直接包含的对象.这不是原始问题的一部分,但我这样做的原因是因为如果我有:
[{"A": 42,"B":{"PropOne":87,"PropTwo":93,"PropThree":78}},
{"A":-72,"B":{"PropOne":97,"PropTwo":43,"PropThree":578}]
Run Code Online (Sandbox Code Playgroud)
......我最终得到了:
[["A","B"],[42,{"PropOne":87,"PropTwo":93,"PropThree":78}],
[-72,{"PropOne":97,"PropTwo":43,"PropThree":578}]]
Run Code Online (Sandbox Code Playgroud)
......这并没有真正保存任何东西.如果我将对象嵌入/展平为其组成键,我最终得到:
[["A","B_PropOne","B_PropTwo","B_PropThree"],[42,87,93,78],[-72,97,43,578]]
Run Code Online (Sandbox Code Playgroud) 我已经针对我的Entity Framework支持的MVC 3站点设置了mvc-mini-profiler.一切都是适当的配置; 在Application_Start中开始分析,在Application_End中结束它,依此类推.分析部分工作得很好.
但是,当我尝试将我的数据模型对象生成交换为提供可分发的版本时,性能会变慢.不是每个SQL查询,但有些查询占用整个页面加载量的大约5倍.(启动IIS Express后第一页加载需要更长时间,但这是持续的.)
可忽略不计的时间(~2ms tops)用于查询,执行和"数据读取"SQL,而这一行:
var person = dataContext.People.FirstOrDefault(p => p.PersonID == id);
Run Code Online (Sandbox Code Playgroud)
...当被包裹时using(profiler.Step())记录为300-400毫秒.我用dotTrace进行了分析,确认时间实际上是照常用于EF(可用的组件确实非常短暂地出现),只是需要更长的时间.
这使我相信连接或其某些组成部分缺少足够的数据,使EF表现更差.
这就是我用来制作上下文对象的东西(我的edmx模型的类叫做DataContext):
var conn = ProfiledDbConnection.Get(
/* returns an SqlConnection */CreateConnection());
return CreateObjectContext<DataContext>(conn);
Run Code Online (Sandbox Code Playgroud)
我最初使用的是mvc-mini-profiler提供的ObjectContextUtils.CreateObjectContext方法.我深入研究它并注意到它设置了一个通配符元数据工作空间路径字符串.由于我将数据库层隔离到一个项目,而将几个MVC站点作为使用代码的其他项目隔离,因此这些路径已经改变,我宁愿更具体.另外,我认为这是性能问题的原因.我将CreateObjectContext功能复制到我自己的项目中以提供此功能,如下所示:
public static T CreateObjectContext<T>(DbConnection connection) where T : System.Data.Objects.ObjectContext {
var workspace = new System.Data.Metadata.Edm.MetadataWorkspace(
GetMetadataPathsString().Split('|'),
// ^-- returns
// "res://*/Redacted.csdl|res://*/Redacted.ssdl|res://*/Redacted.msl"
new Assembly[] { typeof(T).Assembly });
// The remainder of the method is copied straight from the original,
// and I carried over …Run Code Online (Sandbox Code Playgroud) 2017年更新:
实际上,答案是否定的,即使你有使用它也应该非常谨慎.
实际上只有两种方法可以解决这个问题:
a)咬住子弹并手动和精心地转换所有内容,并使用一些验证方法来检查所有内容是否仍按预期运行,如单元/回归测试.使用Linqer等工具(如果有)作为帮助来解决部分问题.
b)从头开始.
没有选择c)让其他东西整齐自动地处理所有事情,并且它不可能涵盖所有情况.有很多事情,T-SQL可以做LINQ无法做到的事情(想到更新,插入和删除),还有很多事情你最好用C#做不同的方式(比如游标).
很少有像这样的问题得到精心设计,详尽无遗的解决方案,可信赖不退回功能(如商业VB6到VB.NET转换器,可以证明花费巨大的努力,因为有大量的潜在客户,你可以在哪里如果出现问题,请拿起电话或律师),所以如果存在这样的工具,你应该非常小心.从LINQ兼容的SQL子集到LINQ的转换是一个有限的问题,并且我认为Linqer可以信任.
这个问题试图找出一个可以帮助选项的工具a)但我想很多读这个的人都在寻找选项c).这个问题和答案的一个子集并不是一个可怕的想法,但它不会自动消除剩余的负担,因为即使许多简单的存储过程也不仅仅是以LINQ可表达的形式进行查询.对于我提到的任何项目,做选项a)仍然太过难以忍受.
原始问题如下:
我有一些项目要维护,使用很多SQL Server存储过程(在T-SQL中).我知道如何维护它们,但由于有许多工具可以自动在不同语言之间进行转换,我想知道是否有任何工具可以将存储过程转换为C#代码?
我不想将它们转换为CLR存储过程; 我只想将数据层中的逻辑迁移到项目的C#端,并自动执行繁琐的工作.大多数存储过程(可能是70%?)都是简单的"SELECT*FROM table WHERE id = @id"事务,它们也可以与Entity Framework一样完成.
我知道它不是T-SQL和C#之间的直线,因为它是从VB.NET到C#并且转换不是那么简单; 例如,你需要在C#中引入一个数据层,而像游标这样的东西没有相应的概念.我只是希望在没有重复的手工劳动的情况下离开存储过程.
因为这已经被错误的假设所质疑:我已经知道了T-SQL,并且给出了这些存储过程中的任何一个的代码,我可以告诉你他们做了什么.我不希望逻辑继续驻留在存储过程中有很好的实际原因.
我有一个UL包含多个链接的列表,每个项目都链接到它自己的链接DIV.当用户将鼠标悬停在UL链接上时,DIV会显示正确的框.
这是我的HTML代码:
<ul class="productlist">
<li><a href="#" id="link0" class="product-link">Link 1</a></li>
<li><a href="#" id="link2" class="product-link">Link 2</a></li>
<li><a href="#" id="link3" class="product-link">Link 3</a></li>
</ul>
<div class="panel-overview boxlink" id="boxlink0"> Something goes here 1 </div>
<div class="panel-overview boxlink" id="boxlink1"> Something goes here 2 </div>
<div class="panel-overview boxlink" id="boxlink2"> Something goes here 3 </div>
Run Code Online (Sandbox Code Playgroud)
以及使其工作的JavaScript(不是JavaScript专家,抱歉):
<script>
$(function() {
var $boxes = $('.boxlink');
$('.productlist .product-link').mouseover(function() {
$boxes.hide().filter('#box' + this.id).show();
});
});
</script>
Run Code Online (Sandbox Code Playgroud)
我想知道如何让盒子每隔3到4秒自动滚动一次.因此,例如,首先DIV打开3秒,然后是第二个,然后是第三个......
这是现场网站,因为我还没有真正描述它.
我正在运行Visual Studio 2012并在单独的解决方案中编写后端Web服务和桌面软件.由于桌面软件需要升级("作为管理员"),我需要在提升的Visual Studio实例中运行桌面解决方案.两种解决方案都包含签名库项目.
当我在Visual Studio实例中打开Web服务解决方案而不提升它时,我得到一个类似的构建错误
无法导入以下密钥文件:Redacted.pfx.密钥文件可能受密码保护.要更正此问题,请尝试再次导入证书,或使用以下密钥容器名称手动将证书安装到强名称CSP:VS_KEY_Redacted.
当我尝试通过这样做来解决这个问题时,它会失败并显示一条错误消息,指出密钥已经存在.
当我尝试排除然后重新包含PFX文件时没有把事情做对,但是在项目属性→登录空白时使"强名称密钥文件"下拉列表.接下来,Web服务解决方案构建,但似乎库没有签名,因为在(提升的)桌面解决方案中,构建失败,"程序集生成失败 - 引用程序集'编辑'没有强名称".
如果我尝试从Web服务解决方案中的下拉列表中再次选择PFX文件(并重新输入密码),我会得到:
导入密钥时出错
尝试引用不存在的令牌
从(提升的)桌面解决方案设置PFX文件可以正常工作,但会将我返回到正方形.
看起来,根据高程,Visual Studio会在不同的密钥库中查找可以解锁PFX的任何内容.我是否必须运行两个提升的Visual Studio实例来解决问题,或者我可以以某种方式告诉它在同一个地方查看?
c# ×2
.net ×1
code-signing ×1
javascript ×1
jquery ×1
json.net ×1
rest ×1
scroll ×1
sql-server ×1
strongname ×1
t-sql ×1