我正在编写WCF服务,并希望公开一些自定义配置元素(例如Custom ConfigurationSection和ConnectionStringSettings),以便我可以修改服务的配置.
我的一个自定义配置元素继承自System.Configuration.ConfigurationElementCollection.当我尝试启动我的WCF服务时,我收到以下错误消息...
类型'System.Configuration.ConfigurationElementCollection'无法序列化.请考虑使用DataContractAttribute属性对其进行标记,并使用DataMemberAttribute属性标记要序列化的所有成员.
有没有办法为此类型实现DataContract?我有我的继承类标有[DataContract]属性.
wcf serialization datacontract datamember configurationelement
没有DataContract属性的类之间有什么区别:
public class BankOperationResult
{
public int CurrentAmount { get; set; }
public bool Success { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和具有DataContract属性的同一个类:
[DataContract]
public class BankOperationResult
{
[DataMember]
public int CurrentAmount { get; set; }
[DataMember]
public bool Success { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的意思是,WCF在编码等时会以不同的方式处理这两种类型吗?
有或没有这些属性我的WCF服务工作...
谢谢,Pawel
有没有办法在DataContract中发送属性的摘要信息?
例如
[DataContract]
public class MyClass
{
/// <summary>
/// My Summary information
/// </summary>
[DataMember]
public int MyProperty {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
是否可以获得获得datacontract的客户?我怀疑它,只是希望有人知道我不知道的事情,这很可能.:)
我有一个ServiceContract返回动态类型,如下所示:
public dynamic LoginViaOpenId(string openIdUrl)
Run Code Online (Sandbox Code Playgroud)
动态返回类型可以是DataContract我定义的,也可以是字符串.但由于我没有使用我DataContract的服务,客户端对此一无所知,也无法访问它.
我的DataContract情况如下:
[DataContract]
public enum OpenIdStatus
{
[EnumMember]
Authenticated,
[EnumMember]
Authenticating,
[EnumMember]
Cancelled,
[EnumMember]
Failed,
[EnumMember]
RedirectToLogon
}
Run Code Online (Sandbox Code Playgroud)
我知道如果我有过可以用来KnownType征服它的分层类型,但我不相信这种情况.任何的想法?
我有一个带有注释的枚举,EnumMember以促进类似于以下内容的JSON.NET序列化:
[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum Status
{
[EnumMember(Value = "NOT_ADMITTED")]
NotAdmitted,
[EnumMember(Value = "ADMITTED")]
Admitted
}
Run Code Online (Sandbox Code Playgroud)
现在,独立于JSON.NET序列化,我想将枚举实例转换为字符串,同时遵守EnumMember数据协定中的注释,例如:
aStatusInstance.ToString() == "NOT_ADMITTED"。
有什么建议么?谢谢!
更新:我的解决方案
我修改了接受的答案中的代码,以创建扩展方法来检索EnumMember值:
public static string GetEnumMemberValue(this Enum enumValue)
{
var type = enumValue.GetType();
var info = type.GetField(enumValue.ToString());
var da = (EnumMemberAttribute[])(info.GetCustomAttributes(typeof(EnumMemberAttribute), false));
if (da.Length > 0)
return da[0].Value;
else
return string.Empty;
}
Run Code Online (Sandbox Code Playgroud) 很多时候,我看到开发人员正在使用DataContract和DataMember属性作为他们的Asp.net Web API模型?
有什么区别和最佳做法?
我有以下代码:
[ServiceContract(Name = "Save{0}")]
public ISave<T> where T : BusinessObject
{
[OperationContract(Name = "Save")]
void Save(T obj);
}
public class SaveCustomer : ISave<Customer>
{
public void Save(Customer obj) { ... }
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我使用IIS/WAS的WCF应用程序不喜欢我给的名字.它不会自动填充它.我看到了这个stackoverflow问题,它有关于为什么名称不会自动格式化的答案.我没有等待微软允许格式化名称,而是看到我是否可以用我自己的名称替换名称的功能.
我只是不确定我需要扩展(哪一类ServiceHost,ServiceHostFactory,DataContractSerializer等),甚至什么方法我要重写,以获得更友好的名称.另外,因为我甚至不知道我要创建什么类,我不知道在哪里可以告诉我的应用程序使用它(Global.asax成员?svc文件?属性?).
我的合同如下:
[DataContract]
public class MyObj
{
[DataMember(IsRequired=true)]
public string StrA {get; private set;}
[DataMember(IsRequired=false)]
public string StrB {get; private set;}
}
Run Code Online (Sandbox Code Playgroud)
究竟是什么IsRequired意思?是否IsRequired=false意味着我可以通过单元化传递一个MyObj跨线的实例,StrB或者它是否意味着我可以传递一个MyObj跨越线的实例StrB而不存在?
如果是后者,我如何实际实例化+发送一个MyObj没有的实例StrB?
我有一个数据访问层,一个服务层和一个表示层.表示层是ASP.NET MVC2 RTM(Web),服务层是WCF(服务).这都是.NET 3.5 SP1.
问题是在服务中,返回的对象用[DataContract]属性标记.Web正在使用AppFabric Cache(aka Velocity)SessionStateProvider来存储会话状态.因此,我在会话中存储的任何内容都必须是可序列化的.
问题就出现了:DataContracts没有标记,[Serializable]并且据我所知,通过将它引入已经标记出[DataContract]某些问题的类,因此我不相信这是一个解决方案.
我最初计划在Web层使用DataContracts,将它们用作与渲染DataContracts相关的视图的模型(可能嵌套在更高级别的ViewModel类中).但是由于会话状态提供程序要求存储在其中的所有对象都是可序列化的,所以我开始重新考虑这种策略.尽管如此,它会很好,因为它们包含使用IDataErrorInfo接口的验证逻辑,并且相同的验证逻辑可以作为模型绑定的一部分在MVC中重用.
您认为什么是让我减少所需工作的最佳方式?
我目前想到了以下不同的方式:
A.在Web项目中创建"ServiceIntegration"部分.
这将是我的控制器和我的WCF服务层之间的中间人.ServiceIntegration部分将使用DataContracts与服务层对话,使用ViewModels与Web层对话,但必须使用双向Transformer在DataContracts和ViewModel之间进行转换.
此外,由于IDataErrorInfo验证不可重复使用,因此有必要为每个DataContract创建一个Validator,它使用Transformer从ViewModel转换为DataContract,使用IDataErrorInfo执行验证并返回其结果.然后将在控制器的动作方法中使用(例如if (!MyValidator.IsValid(viewModel)) return View();)
需要不同的类:xDataContract,xViewModel,xTransformer,xValidator
B.在Web项目中创建"SessionIntegration"部分
这将是控制器(或访问会话的任何内容)和会话本身之间的中间人.任何需要访问会话的内容都将通过此课程.DataContracts将在整个应用程序中使用,除非它们存储在会话中.SessionIntegration部分负责将DataContract转换为某种ISerializable形式,然后返回.由于在DataContract上使用了IDataErrorInfo接口,因此无需额外的Validator.
需要不同的类:xDataContract,xTransformer,xSerializableForm
注意:在两种情况下仍然会有ViewModels,但是(B)我可以从DataContracts组成ViewModels.
(B)具有不需要额外验证器的好处.
在我完全实现(A)/(B)之前,我想要一些反馈.目前,我开始倾向于(B),但是,(A)可能更灵活.无论哪种方式,对于它的价值而言似乎太过分了.有没有其他人遇到过这个问题,你是否同意/不同意我,和/或你有其他办法解决这个问题吗?
谢谢,
詹姆士
asp.net-mvc session datacontract iserializable session-state-provider
我无法为属性指定自定义名称。我从服务器收到一些无法更改的JSON,但属性名称却很丑陋。我希望C#代码遵循命名约定。
下面是我的代码(result0.StringValue保持为空):
[TestClass()]
public class WebServiceResultConverterTest
{
[DataContract(Name = "SimpleObject")]
private class SimpleObject
{
[DataMember(Name = "str_value")]
public String StringValue { get; set; }
[DataMember(Name = "int_value")]
public String IntValue { get; set; }
}
[TestMethod()]
public void DeserializeTest()
{
String input0 = @"{
""str_value"": ""This is a test string"",
""int_value"": 1664
}";
JavaScriptSerializer serializer = new JavaScriptSerializer();
SimpleObject result0 = serializer.Deserialize<SimpleObject>(input0);
Assert.AreEqual("This is a test string", result0.StringValue);
Assert.AreEqual(1664, result0.IntValue);
}
}
Run Code Online (Sandbox Code Playgroud) datacontract ×10
wcf ×6
c# ×3
asp.net ×2
datamember ×2
asp.net-mvc ×1
data-members ×1
enums ×1
generics ×1
json ×1
json.net ×1
session ×1