I want to set string DataMember as mandatory, I have set "IsRequired = true" but it is showing as optional in XML request.
[MessageContract(WrapperName = "tourinforequest")]
public class TourInfoRequest
{
public TourInfoRequest()
{
Request = new TourInfoRequestRequestData();
}
[MessageBodyMember]
public TourInfoRequestRequestData Request;
}
public class TourInfoRequestRequestData : BaseRequest
{
[DataMember(Order = 1, IsRequired = true ), XmlElement(ElementName = "tourcode")]
public string TourCode { get; set; }
[DataMember(Order = 2, IsRequired = true), XmlElement(ElementName = "depdate")]
public DateTime DepartureDate { get; set; }
}
Related
Using c# 8. I have a set of base Interfaces with default implementation:
public interface IEventBase
{
string PostRoutingKey { get; set; }
string EventSource => Assembly.GetEntryAssembly()?.GetName().Name;
long Timestamp => DateTimeOffset.UtcNow.ToUnixTimeSeconds();
Guid EventId => Guid.NewGuid();
string EventKey { get; set; }
}
public interface IActionNotifiable : IEventBase
{
[JsonProperty(Required = Required.Always)]
string SenderName { get; set; }
[JsonProperty(Required = Required.Always)]
string ReceiverName { get; set; }
[JsonProperty(Required = Required.Always)]
string SenderId { get; set; }
[JsonProperty(Required = Required.Always)]
string ReceiverId { get; set; }
string Title { get; set; }
string ShortDescription { get; set; }
string LongDescription { get; set; }
ActionNotifiableStatusEnum Status { get; set; }
Dictionary<string, string> ExtraProperties { get; set; }
}
public interface IPush : IActionNotifiable
{
[JsonProperty(Required = Required.Always)]
public string CallbackUrl { get; set; }
}
public class DerivedConcretePush : IPush
{
public string PostRoutingKey { get; set; }= string.Empty;
public string EventKey { get; set; }= string.Empty;
public string SenderName { get; set; }= string.Empty;
public string ReceiverName { get; set; }= string.Empty;
public string SenderId { get; set; }= string.Empty;
public string ReceiverId { get; set; }= string.Empty;
public string Title { get; set; }= string.Empty;
public string ShortDescription { get; set; }= string.Empty;
public string LongDescription { get; set; }= string.Empty;
public ActionNotifiableStatusEnum Status { get; set; }
public Dictionary<string, string> ExtraProperties { get; set; } = new Dictionary<string, string>();
public string CallbackUrl { get; set; }= string.Empty;
}
And trying to Serialize the object using the SerilizeObject from https://www.newtonsoft.com/json, doing something like this:
var message = JsonConvert.SerializeObject(#event, JsonConvertExtension.GetCamelCaseSettings());
and my JsonSettings looks like this:
public static JsonSerializerSettings GetCamelCaseSettings()
{
return new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
},
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto
};
}
I get something like this:
{
"postRoutingKey": "",
"eventKey": "sericy-rabbiteventconsumer-cli.DerivedConcretePush",
"senderName": "",
"receiverName": "",
"senderId": "",
"receiverId": "",
"title": "just a tittle",
"shortDescription": "",
"longDescription": "body",
"status": 0,
"extraProperties": {},
"callbackUrl": ""
}
I had tried playing around with TypeNameHandling and passing the IEventBase type to SerializeObject.
What is the best way to serialize the object including all the Interface properties?
I end up creating a custom contract resolver:
public class InterfaceContractResolver : DefaultContractResolver
{
private readonly Type[] _interfaceTypes;
private readonly ConcurrentDictionary<Type, Type> _typeToSerializeMap;
public InterfaceContractResolver(params Type[] interfaceTypes)
{
_interfaceTypes = interfaceTypes;
_typeToSerializeMap = new ConcurrentDictionary<Type, Type>();
NamingStrategy = new CamelCaseNamingStrategy();
}
protected override IList<JsonProperty> CreateProperties(
Type type,
MemberSerialization memberSerialization)
{
var typeToSerialize = _typeToSerializeMap.GetOrAdd(
type,
t => _interfaceTypes.FirstOrDefault(
it => it.IsAssignableFrom(t)) ?? t);
var props = base.CreateProperties(typeToSerialize, memberSerialization);
// mark all props as not ignored
foreach (var prop in props)
{
prop.Ignored = false;
}
return props;
}
}
internal static class JsonConvertExtension
{ {
public static JsonSerializerSettings GetCamelCaseSettings() public static JsonSerializerSettings SetupJsonSerializerSettings(Type eventType)
{ {
var eventTypes = eventType.GetParentTypes().ToArray();
return new JsonSerializerSettings return new JsonSerializerSettings
{ {
ContractResolver = new DefaultContractResolver ContractResolver = new InterfaceContractResolver(eventTypes),
{ Formatting = Formatting.Indented,
NamingStrategy = new CamelCaseNamingStrategy() TypeNameHandling = TypeNameHandling.Auto,
},
Formatting = Formatting.Indented
}; };
And calling it using the type:
var message = JsonConvert.SerializeObject(#event, JsonConvertExtension.SetupJsonSerializerSettings(#event.GetType()));
There is a note in the developer road map from December of 2013 saying, "Lock/Unlock – We’ve added support for locking and unlocking files into the V2 API."
I've been all through the V2 API (for c#) and cannot find it anywhere. I expected to find something in the BoxFilesManager class or as something you would pass to UpdateInformationAsync within the BoxFileRequest class.
So is there a way to lock/unlock a file?
Great question. In order to see the current lock status of a file do a
GET https://api.box.com/2.0/files/7435988481/?fields=lock
If there is no lock on the file, you'll get something like this back:
{
"type": "file",
"id": "7435988481",
"etag": "0",
"lock": null
}
If you want to lock a file, you need to do a PUT (update) on the /files/ endpoint with a body that tells us what type of lock, and when to release it. Like this:
PUT https://api.box.com/2.0/files/7435988481/?fields=lock
{"lock": {
"expires_at" : "2014-05-29T19:03:04-07:00",
"is_download_prevented": true
}
}
You'll get a response confirming your lock was created:
{
"type": "file",
"id": "7435988481",
"etag": "1",
"lock": {
"type": "lock",
"id": "14516545",
"created_by": {
"type": "user",
"id": "13130406",
"name": "Peter Rexer gmail",
"login": "prexer#gmail.com"
},
"created_at": "2014-05-29T18:03:04-07:00",
"expires_at": "2014-05-29T19:03:04-07:00",
"is_download_prevented": true
}
}
Since there isn't a lock/unlock yet, I created a Lock Manager based on the existing managers:
class BoxCloudLockManager : BoxResourceManager
{
#region Lock/Unlock Classes
[DataContract]
internal class BoxLockRequestInfo
{
[DataMember(Name = "status")]
public string Status { get; set; }
//[DataMember(Name = "expires_at")]
//public string ExpiresAt { get; set; }
[DataMember(Name = "is_download_prevented")]
public bool IsDownloadPrevented { get; set; }
}
[DataContract]
internal class BoxLockRequest
{
[DataMember(Name = "lock")]
public BoxLockRequestInfo Lock { get; set; }
}
#endregion
const string LockFileString = "{0}/?fields=lock";
public BoxCloudLockManager(IBoxConfig config, IBoxService service, IBoxConverter converter, IAuthRepository auth)
: base(config, service, converter, auth)
{
}
public async Task<BoxLockInfo> LockAsync(string documentId,bool isDownloadPrevented = true)
{
var lockRequest = new BoxLockRequest { Lock = new BoxLockRequestInfo { Status = "lock", IsDownloadPrevented = isDownloadPrevented } };
BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(LockFileString, documentId))
.Method(RequestMethod.Put)
.Payload(_converter.Serialize(lockRequest));
IBoxResponse<BoxLockInfo> response = await ToResponseAsync<BoxLockInfo>(request).ConfigureAwait(false);
return response.ResponseObject;
}
public async Task<BoxLockInfo> UnlockAsync(string documentId)
{
BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(LockFileString, documentId))
.Method(RequestMethod.Put)
.Payload("{\"lock\":null}");
IBoxResponse<BoxLockInfo> response = await ToResponseAsync<BoxLockInfo>(request).ConfigureAwait(false);
return response.ResponseObject;
}
public async Task<BoxLockInfo> GetLockInfoAsync(string documentId)
{
BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(LockFileString, documentId))
.Method(RequestMethod.Get);
IBoxResponse<BoxLockInfo> response = await ToResponseAsync<BoxLockInfo>(request).ConfigureAwait(false);
return response.ResponseObject;
}
}
I derived a class from BoxClient, adding a LockManager and instantiate it within the Constructor.
Here is the Lock Info:
[DataContract]
public class BoxLockedBy
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "login")]
public string Login { get; set; }
}
[DataContract]
public class BoxLockDetails
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "created_by")]
public BoxLockedBy CreatedBy { get; set; }
[DataMember(Name = "created_at")]
public string CreatedAt { get; set; }
[DataMember(Name = "expires_at")]
public string ExpiresAt { get; set; }
[DataMember(Name = "is_download_prevented")]
public bool IsDownloadPrevented { get; set; }
}
[DataContract]
public class BoxLockInfo
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "etag")]
public string Etag { get; set; }
[DataMember(Name = "lock")]
public BoxLockDetails LockDetails { get; set; }
}
i'm developing a mobile air application. for comunications i'm using a wcf service.
now my problem is this, i'm trying to deserialize an array of arrays using json.net. the sub arrays are typed.
so, my classes in the mobile side are the following:
package Model.VO.PHCDATA
{
[Bindable]
[RemoteClass(alias="Model.PCHModel.VODadosPHC")]
public class VoBi
{
private var _BIstamp:String;
private var _ivaincl:Number;
private var _vendnm:String;
private var _vendedor:Number;
private var _iva:Number;
private var _lordem:Number;
private var _tabiva:Number;
private var _txiva:Number;
private var _familia:String;
....
}
}
and the other is:
package Model.VO.PHCDATA
{
[Bindable]
[RemoteClass(alias="Model.PCHModel.VODadosPHC")]
public class VOBO
{
private var _BOstamp:String;
private var _vendedor:Number;
private var _vendnm:String;
....
}
}
and the corresponding c# classes are the following:
[DataContract(Name = "VoBi")]
public class VoBi
{
[DataMember(IsRequired = true, Name = "BIstamp", Order = 0)]
public string BIstamp { get; set; }
[DataMember(IsRequired = true, Name = "ivaincl", Order = 1)]
public decimal ivaincl { get; set; }
[DataMember(IsRequired = true, Name = "vendnm", Order = 2)]
public string vendnm { get; set; }
[DataMember(IsRequired = true, Name = "vendedor", Order = 3)]
public decimal vendedor { get; set; }
....
}
and the other one:
[DataContract(Name = "VOBO")]
public class VOBO
{
[DataMember(IsRequired = true, Name = "BOstamp", Order = 0)]
public string BOstamp { get; set; }
[DataMember(IsRequired = true, Name = "vendedor", Order = 1)]
public decimal vendedor { get; set; }
[DataMember(IsRequired = true, Name = "vendnm", Order = 2)]
public string vendnm { get; set; }
[DataMember(IsRequired = true, Name = "nmdos", Order = 3)]
public string nmdos { get; set; }
[DataMember(IsRequired = true, Name = "ndos", Order = 4)]
public decimal ndos { get; set; }
.....
}
the corresponding json string to be sent to the server is this one:
{
"DADOSBI": [
{
"edebito": 0,
"desconto": 92.121,
"vendedor": 0,
"desc2": 222.343,
"iva": 23,
"ettdeb": 123.555,
"lordem": 12,
"tabiva": 2.1,
....
},
{
"edebito": 0,
"desconto": 92.121,
"vendedor": 1,
"desc2": 222.343,
"iva": 23,
"ettdeb": 123.555,
"lordem": 12,
"tabiva": 2.1,
....
}
],
"DADOSBO": [
{
"estab": 123.88,
"etotaldeb": 123,
"obs": "",
"vendedor": 0,
"statuspda": "qqqqqqqqqqqq",
"ebo_2tvall": 12,
"ebo_2tdes1": 12.11,
...
},
{
"estab": 123.88,
"etotaldeb": 123,
"obs": "",
"vendedor": 1,
"statuspda": "qqqqqqqqqqqq",
"ebo_2tvall": 12,
....
}
]
}
how do i handle this? do i use json.net CustomCreationConverter to deserialize the data? and obtain the corresponding arrays filled with the classes i've mentioned, or i use another approach?
help would be appreciated.
thanks in advance.
Assuming your top class looks as follows (if you do not have then create one if it is effort less otherwise we need to go a better solution)
internal class TopClass
{
[JsonProperty("DADOSBI")]
public IList<VoBi> VOBiList { get; set; }
[JsonProperty("DADOSBO")]
public IList<VOBO> VOBOList { get; set; }
}
Then simply deserialise using
var topClass = JsonConvert.DeserializeObject<TopClass>( json);
If this is not the answer you are looking for then please update the question with more information
I'm new to MVC and trying to figure out how to set default values for partial classes. I have been searching for 2 days now, and can't get anything to work. Here is a supposed solution, but it doesn't work for me. I also tried the [DefaultValue(10)] data annotation.
Here is the auto generated partial class created from the edmx file
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace OTIS.Models.Admin
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Company
{
public Company()
{
this.Facilities = new HashSet<Facility>();
}
public int CompanyID { get; set; }
[Required]
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public decimal ItemMargin { get; set; }
public decimal ServicesMargin { get; set; }
public decimal InvoiceTimeIncrement { get; set; }
public decimal CashDiscountPct { get; set; }
public decimal BaseServiceHourlyRate { get; set; }
public decimal HourlyPremiumRush { get; set; }
public decimal HourlyPremiumLate { get; set; }
public decimal HourlyPremiumCustomerMaterial { get; set; }
public int CreatedByID { get; set; }
public System.DateTime CreatedOn { get; set; }
public int ModifiedBy { get; set; }
public System.DateTime ModifiedOn { get; set; }
public virtual UserProfile UserProfile { get; set; }
public virtual UserProfile UserProfile1 { get; set; }
public virtual ICollection<Facility> Facilities { get; set; }
}
}
Here is my partial class I created to add annotations.
namespace OTIS.Models.Admin
{
[MetadataType(typeof(CompanyMD))]
public partial class Company
{
//public Company()
//{
// //private System.DateTime _currentDateTime = DateTime.Now;
// ////Set Default Values
// //CreatedByID = (int)Membership.GetUser().ProviderUserKey;
// //CreatedOn = _currentDateTime;
// //ModifiedBy = (int)Membership.GetUser().ProviderUserKey;
// //ModifiedOn = _currentDateTime;
//}
public string FullAddress
{
get
{
return this.City + ", " + this.State + " " + this.PostalCode;
}
}
public class CompanyMD
{
private System.DateTime _currentDateTime = DateTime.Now;
private int _currentUser = (int)Membership.GetUser().ProviderUserKey;
[Display(Name = "Company ID")]
public int CompanyID { get; set; }
[Required]
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Display(Name = "Address")]
public string Address1 { get; set; }
[Display(Name = "Address 2")]
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
[Display(Name = "Zip")]
public string PostalCode { get; set; }
[Display(Name = "Address")]
public string FullAddress { get; set; }
[Display(Name = "Material Margin")]
public decimal ItemMargin { get; set; }
[Display(Name = "Overtime Margin")]
public decimal ServicesMargin { get; set; }
[Display(Name = "Invoice Hour Increment")]
public decimal InvoiceTimeIncrement { get; set; }
private decimal _cashDiscountPct;
[Display(Name = "Cash Discount %")]
[DisplayFormat(DataFormatString = "{0:P2}")]
public decimal CashDiscountPct
{
get { return _cashDiscountPct; }
set { _cashDiscountPct = value/100; }
}
[Display(Name = "Base Hourly Rate ($/Hr)")]
[DataType(DataType.Currency), DisplayFormat(DataFormatString = "{0:C2}", ApplyFormatInEditMode = true)]
public decimal BaseServiceHourlyRate { get; set; }
[Display(Name = "Rush Premium ($/Hr)")]
[DataType(DataType.Currency), DisplayFormat(DataFormatString = "{0:C2}", ApplyFormatInEditMode = true)]
public decimal HourlyPremiumRush { get; set; }
[Display(Name = "Late Premium ($/Hr)")]
[DataType(DataType.Currency), DisplayFormat(DataFormatString = "{0:C2}", ApplyFormatInEditMode = true)]
[DefaultValue(75)]
public decimal HourlyPremiumLate { get; set; }
[Display(Name = "Cust Material Premium ($/Hr)")]
[DataType(DataType.Currency), DisplayFormat(DataFormatString = "{0:C2}", ApplyFormatInEditMode = true)]
public decimal HourlyPremiumCustomerMaterial { get; set; }
[Display(Name = "Created By")]
public int CreatedByID { get; set; }
//{
// get { return _currentUser; }
// set { _currentUser = value; }
//}
[Display(Name = "Created On")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
//[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public System.DateTime CreatedOn
{
get { return _currentDateTime; }
set { _currentDateTime = value; }
}
[Display(Name = "Modified By")]
public int ModifiedBy { get; set; }
//{
// get { return _currentUser; }
// set { _currentUser = value; }
//}
[Display(Name = "Modified On")]
public System.DateTime ModifiedOn
{
get { return _currentDateTime; }
set { _currentDateTime = value; }
}
}
}
}
And then in my controller, I instantiate a new instance of the class to initialize it, but the values I set don't get set.
//
// GET: /Company/Create
public ActionResult Create()
{
ViewBag.CreatedByID = new SelectList(db.UserProfiles, "UserId", "UserName");
ViewBag.ModifiedBy = new SelectList(db.UserProfiles, "UserId", "UserName");
Company newCompany = new Company();
return View(newCompany);
}
Sorry this is so late, but I just solved a similar scenario myself.
I think the problem is how you refer to the partial class. It should be an empty reference to the partial class with no code. EF uses this "declaration" to link your partial class to your metadata class. So, your metadata class should look like this:
namespace OTIS.Models.Admin
{
[MetadataType(typeof(CompanyMD))]
public partial class Company
{} // <-- note the close bracket!
public class CompanyMD
{
private System.DateTime _currentDateTime = DateTime.Now;
private int _currentUser = (int)Membership.GetUser().ProviderUserKey;
public string FullAddress
{
get
{
return this.City + ", " + this.State + " " + this.PostalCode;
}
}
[Display(Name = "Company ID")]
public int CompanyID { get; set; }
[Required]
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
// ....etc.... removed for brevity
} // close metadata class
} // close namespace
Hope this helps!
I found I needed to handle this in my Repository Class in a GetNew() method that would populate the default values of a new instance of the class.
I have a DataContract that looks like:
[DataContract(Name = User.Root, Namespace = "")]
public class RegisterUser
{
[DataMember(Name = User.EmailAddress)]
public string EmailAddress { get; set; }
[DataMember(Name = User.UserName)]
public string UserName { get; set; }
[DataMember(Name = User.Password)]
public string Password { get; set; }
[DataMember(Name = User.FirstName)]
public string FirstName { get; set; }
[DataMember(Name = User.LastName)]
public string LastName { get; set; }
[DataMember(Name = User.PhoneNumber)]
public string PhoneNumber { get; set; }
[DataMember(Name = "RequestMessage")]
public string RequestMsg { get; set; }
}
And I would like to get the elements out of it. So instead of
<ROOT> <Element1/>...</ROOT>. I would just like to get <Element1/> (for partial xsd validation).
I thought I could use this function:
public static string Serialize<T>(T obj)
{
DataContractSerializer ser = new DataContractSerializer(obj.GetType());
String text;
using (MemoryStream memoryStream = new MemoryStream())
{
ser.WriteObject(memoryStream, obj);
byte[] data = new byte[memoryStream.Length];
Array.Copy(memoryStream.GetBuffer(), data, data.Length);
text = Encoding.UTF8.GetString(data);
}
return text;
}
and just pass it
string str = Serialize(test.EmailAddress);
That works great but the xml looks like:
"<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">myemail.com</string>"
I lost the DataMember info. How can I retain that as well?
Use WriteObjectContent instead of WriteObject:
http://msdn.microsoft.com/en-us/library/ms573853.aspx