有没有办法可以自动添加注释到JSON.Net的序列化输出?
理想情况下,我认为它类似于以下内容:
public class MyClass
{
[JsonComment("My documentation string")]
public string MyString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
或者(如果可以避免注释,则更好):
public class MyClass
{
/// <summary>
/// My documentation string
/// </summary>
public string MyString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
会产生:
{
//My documentation string
"MyString": "Test"
}
Run Code Online (Sandbox Code Playgroud)
我问的原因是我们使用Json.NET来序列化配置文件,以后可以手动更改.我想在我的C#配置类中包含文档,并在JSON中重现这些文档,以帮助以后可能需要更改文件的人.
更新:正如RoToRa在下面指出的那样,在JSON规范中技术上不允许发表评论(请参阅http://www.json.org上方便的语法图).但是,Json.NET站点上的功能表包括:
支持阅读和撰写评论
并Newtonsoft.Json.JsonTextWriter.WriteComment(string)存在输出评论.我对创建注释的简洁方法感兴趣,而不是JsonTextWriter直接使用.
我正在我的csproj文件中设置一些配置,这些配置将针对不同的框架版本.理想情况下,我想要'Debug - 3.5','Debug - 4.0','Release - 3.5'和'Release - 4.0'的配置.
在我的csproj文件中,我想做类似以下的事情:
<PropertyGroup Condition=" '${Configuration}' ends with '3.5' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup
<PropertyGroup Condition=" '${Configuration}' ends with '4.0' ">
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup
... check for "starts with Debug" to define Optimize etc.
Run Code Online (Sandbox Code Playgroud)
但是,我不知道如何检查${Configuration}以特定字符串开头/结尾.是否有捷径可寻?
编辑:下面标记的答案指出我正确的方向,这导致我去:
<PropertyGroup Condition="$(Configuration.Contains('Debug'))">
... setup pdb, optimize etc.
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('3.5'))">
... set target framework to 3.5
</PropertyGroup>
... and so on for Release and 4.0 variations
Run Code Online (Sandbox Code Playgroud) 我有一个使用ReaderWriterLockSlim的类,它有一个read方法和一个write方法,它使用read方法来检索要修改的元素.一个简单的例子是:
class FooLocker
{
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
List<Foo> fooList = new List<Foo>();
public void ChangeFoo(int index, string bar)
{
locker.EnterWriteLock();
try
{
Foo foo = GetFoo(index);
foo.Bar = bar;
}
finally
{
locker.ExitWriteLock();
}
}
public Foo GetFoo(int index)
{
locker.EnterReadLock(); //throws System.Threading.LockRecursionException
try
{
return fooList[index];
}
finally
{
locker.ExitReadLock();
}
}
//snipped code for adding instances etc.
}
Run Code Online (Sandbox Code Playgroud)
如上所述,此代码LockRecursionException在调用时抛出,ChangeFoo()因为在GetFoo()尝试输入读锁定时已经保持写锁定.
我已经检查了文档ReaderWriterLockSlim,我可以LockRecursionPolicy.SupportsRecursion用来允许上面的工作.但是,文档还建议不应将此用于任何新开发,并且只应在升级现有代码时使用.
鉴于此,在write方法可以使用只读方法检索需要修改的事物的情况下,实现相同结果的最佳实践是什么?
我有一个IConfig对象,其中包含我的应用程序中使用的设置.目前,我将整个对象注入到需要它的每个对象的构造函数中,如下所示:
public interface IConfig
{
string Username { get; }
string Password { get; }
//... other settings
}
public class Foo : IFoo
{
private readonly string username;
private readonly string password;
public Foo(IConfig config)
{
this.username = config.Username;
this.password = config.Password;
}
}
Run Code Online (Sandbox Code Playgroud)
缺点是IConfig包含大量设置,因为它是从整个配置文件中反序列化的,因此不必注入整个对象.我想要做的是将构造函数更改为Foo(string username, string password)只接收它需要的设置.这也使得创建Foo测试对象变得更加容易(不必IConfig仅仅为了创建而设置Foo).我想直接在我的绑定构造函数参数NinjectModule,如下所示:
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IConfig>().To<JsonConfig>()
.InSingletonScope();
Bind<IFoo>().To<Foo>()
.WithConstructorArgument("username", IConfig.Username)
.WithConstructorArgument("password", …Run Code Online (Sandbox Code Playgroud) 在我的WCF服务中,我有一个自定义消息检查器,用于将传入消息验证为XML Schema的原始XML.消息检查器具有一些依赖性(例如记录器和XML架构集合).我的问题是,我可以使用依赖注入框架(我目前正在使用Ninject)来实例化这些自定义行为并自动注入依赖项吗?
我做了一个简单的例子来展示这个概念:
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using Ninject.Extensions.Logging;
public class LogMessageInspector : IDispatchMessageInspector
{
private readonly ILogger log;
public LogMessageInspector(ILogger log)
{
this.log = log;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
LogMessage(ref request);
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
LogMessage(ref reply);
}
private void LogMessage(ref Message message)
{
//... copy the message and log using this.log ...
}
}
public class LogMessageBehavior : IEndpointBehavior
{
private readonly …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一些代码,这些代码将使Web服务并行调用多个不同的服务器,因此TPL似乎是一个明显的选择.
只有我的一个Web服务调用将返回我想要的结果,而其他所有调用都不会.我正试图找出一种有效的方法,Task.WaitAny当Task匹配条件的第一个返回时,只有解锁.
我尝试过,WaitAny但无法确定过滤器的位置.我到目前为止:
public void SearchServers()
{
var servers = new[] {"server1", "server2", "server3", "server4"};
var tasks = servers
.Select(s => Task<bool>.Factory.StartNew(server => CallServer((string)server), s))
.ToArray();
Task.WaitAny(tasks); //how do I say "WaitAny where the result is true"?
//Omitted: cancel any outstanding tasks since the correct server has been found
}
private bool CallServer(string server)
{
//... make the call to the server and return the result ...
}
Run Code Online (Sandbox Code Playgroud)
编辑:快速澄清,以防上面有任何混淆.我正在尝试执行以下操作:
Task进行检查我有一个使用webHttpBinding端点的C#WCF服务,该端点将以JSON格式接收和返回数据.要发送/接收的数据需要使用多态类型,以便可以在同一"数据包"中交换不同类型的数据.我有以下数据模型:
[DataContract]
public class DataPacket
{
[DataMember]
public List<DataEvent> DataEvents { get; set; }
}
[DataContract]
[KnownType(typeof(IntEvent))]
[KnownType(typeof(BoolEvent))]
public class DataEvent
{
[DataMember]
public ulong Id { get; set; }
[DataMember]
public DateTime Timestamp { get; set; }
public override string ToString()
{
return string.Format("DataEvent: {0}, {1}", Id, Timestamp);
}
}
[DataContract]
public class IntEvent : DataEvent
{
[DataMember]
public int Value { get; set; }
public override string ToString()
{
return string.Format("IntEvent: {0}, {1}, {2}", Id, Timestamp, Value);
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试将Gerrit设置为使用我们的企业Active Directory进行身份验证.我知道有很多人设法让这个工作,但它对我不起作用.
如果我运行ldapsearch如下命令,我得到正确的结果,所以我知道我的搜索字符串是正确的:
ldapsearch -h myserver -b "CN=Users,DC=mycompany,DC=com" -D "CN=adam,CN=Users,DC=mycompany,DC=com" -w mypassword "(sAMAccountName=adam)"
Run Code Online (Sandbox Code Playgroud)
但是在我的Gerrit配置中使用这些相同的设置不起作用:
[auth]
type = LDAP
[ldap]
server = ldap://myserver
accountBase = CN=Users,DC=mycompany,DC=com
groupBase = OU=Gerrit,DC=mycompany,DC=com
user = CN=adam,CN=Users,DC=mycompany,DC=com
password = mypassword
referral = follow
accountPattern = (sAMAccountName=${username})
groupPattern = (cn=${groupname})
accountFullName = displayName
accountMemberField = memberOf
accountEmailAddress = mail
Run Code Online (Sandbox Code Playgroud)
当我尝试使用我的帐户登录时,我得到以下异常etc/error_log:
[2012-05-04 10:03:04,595] ERROR com.google.gerrit.server.auth.ldap.LdapRealm : Cannot query LDAP to autenticate user
javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: DSID-0C090627, comment: In order …Run Code Online (Sandbox Code Playgroud) 我正在使用工厂返回数据库:
Bind<IDataSenderFactory>()
.ToFactory();
public interface IDataSenderFactory
{
IDataSender CreateDataSender(Connection connection);
}
Run Code Online (Sandbox Code Playgroud)
我有两种不同的数据集实现(WCF和远程处理),它们采用不同的类型:
public abstract class Connection
{
public string ServerName { get; set; }
}
public class WcfConnection : Connection
{
// specificProperties etc.
}
public class RemotingConnection : Connection
{
// specificProperties etc.
}
Run Code Online (Sandbox Code Playgroud)
我试图使用Ninject根据从参数传递的Connection类型绑定这些特定类型的数据库.我尝试了下面的失败:
Bind<IDataSender>()
.To<RemotingDataSender>()
.When(a => a.Parameters.Single(b => b.Name == "connection") as RemotingConnection != null)
Run Code Online (Sandbox Code Playgroud)
我相信这是因为'.'只提供一个请求,我需要完整的上下文才能检索实际参数值并检查其类型.我不知道该做什么,除了使用命名绑定,实际上实现工厂并将逻辑放在那里,即
public IDataSender CreateDataSender(Connection connection)
{
if (connection.GetType() == typeof(WcfConnection))
{
return resolutionRoot.Get<IDataSender>("wcfdatasender", new ConstructorArgument("connection", connection));
}
return resolutionRoot.Get<IDataSender>("remotingdatasender", new ConstructorArgument("connection", …Run Code Online (Sandbox Code Playgroud) 我有一个REST API,我想从AngularJS服务调用,如下所示:
angular.module('myModule').service('MyApi', ['$http', function($http) {
return ({
resources: resources,
details: details
});
function resources() {
return $http.jsonp('/api/resources');
}
function details(key) {
return $http.jsonp('/api/details/' + id);
}
}]);
Run Code Online (Sandbox Code Playgroud)
还有其他实现细节,例如认证不重要.API由第三方提供,因此我无法更改它.
GET /api/resources 返回类似于:
[{ "key": "one" }, { "key": "two" }]
Run Code Online (Sandbox Code Playgroud)
GET /api/details/one 返回类似于:
{ "count": 5 }
Run Code Online (Sandbox Code Playgroud)
然后我有一个控制器,我想调用MyApi.resources(),等待结果,然后为每个结果,调用MyApi.details(resource).当最后的调用MyApi.details(resource)完成时,我想运行一个函数来聚合一组细节中的一些结果,但是我不知道如何在最后触发它.
我的控制器目前看起来像这样:
angular.module('myModule').controller('MyCtrl', ['$scope', 'MyApi', function($scope, MyApi) {
$scope.results = new Array();
MyApi.resources().then(function(response) {
var resources = response.data;
var length = resources.length;
for (var i = 0; …Run Code Online (Sandbox Code Playgroud) c# ×7
ninject ×3
json ×2
wcf ×2
angularjs ×1
asynchronous ×1
binding ×1
conditional ×1
gerrit ×1
git ×1
javascript ×1
json.net ×1
ldap ×1
msbuild ×1
polymorphism ×1
rest ×1