我创建了一个json,用于保存公司业务逻辑的设置。现在的问题是,如果一天不起作用,我应该在json这个结构中:
{"monday":{"start":"09:00","end":"19:00","breaks":[{"start":"10:30","end":"10:40"},{"start":"15:30","end":"16:40"}]},"tuesday":null,"...
如何看待monday
有一个开始和结束工作时段,并且还有一个breaks
表示非工作时间时段。无论如何,我从我的代码得到的结果是:
{"monday":{"start":"09:00","end":"19:00","breaks":[]},"tuesday":{"start":null,"end":null,"breaks":[]},
tuesday
是一个没有工作的日子,所以我希望获得将json放在顶部,如我所示。这是我的代码:
Public Class WorkDay 'working day
<JsonProperty("start")>
Public Property starttime As String
<JsonProperty("end")>
Public Property endtime As String
Public Property breaks As New List(Of Break)
End Class
Public Class Break 'Breaks time slot
<JsonProperty("start")>
Public Property starttime As String
<JsonProperty("end")>
Public Property endtime As String
End Class
Public Class WorkWeek 'Class for working days
Public Property monday As WorkDay
Public Property tuesday As WorkDay
Public Property wednesday As WorkDay
Public Property thursday As WorkDay
Public Property friday As WorkDay
Public Property saturday As WorkDay
Public Property sunday As WorkDay
'Instance
Public Sub New()
monday = New WorkDay
tuesday = New WorkDay
wednesday = New WorkDay
thursday = New WorkDay
friday = New WorkDay
saturday = New WorkDay
sunday = New WorkDay
End Sub
End Class
班级WorkDay
每天都以monday, tuesday, wednesday etc...
的形式出现。我还有休息时间段的break
类。以及课程WorkWeek
中的天数列表。现在我按照json
这样的某一天定价:
WorkWeek.tuesday.starttime = tuesday_start.Text
WorkWeek.tuesday.endtime = tuesday_end.Text
每天都在select stament
这样:
For Each c As CheckBox In GroupBox2.Controls.OfType(Of CheckBox)
If c.Checked = True Then
'Check working day
Select Case c.Name
Case "monday"
WorkWeek.monday.starttime = monday_start.Text
WorkWeek.monday.endtime =monday_end.Text
Case "tuesday"
WorkWeek.tuesday.starttime = tuesday_start.Text
WorkWeek.tuesday.endtime = tuesday_end.Text
'Generating..
Dim jstr = JsonConvert.SerializeObject(WorkWeek)
checked
属性出现在工作日,事实上我的操作员可以取消选中非工作日。所以我的代码只对工作日进行了评估。我想知道如果星期二是非工作日,我可以设置"tuesday":null,"
而不是"tuesday":{"start":null,"end":null,"breaks":[]}
。想法?
答案 0 :(得分:1)
罗兰是正确的。
或者您可以添加自己的自定义转换器:
Friend Class WorkWeekConverter
Inherits JsonConverter
Private ReadOnly _type as Type = GetType(WorkWeek)
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Dim ww = DirectCast(value, WorkWeek)
writer.WriteStartObject()
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.monday))
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.tuesday))
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.wednesday))
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.thursday))
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.friday))
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.saturday))
WriteWorkDay(writer, ww, serializer, NameOf(WorkWeek.sunday))
writer.WriteEndObject()
End Sub
Private Sub WriteWorkDay(writer As JsonWriter, ww As WorkWeek, serializer As JsonSerializer, dayOfWeek As String)
Dim prop = _type.GetProperty(dayOfWeek)
Dim value = DirectCast(prop.GetValue(ww), WorkDay)
writer.WritePropertyName(dayOfWeek)
If value?.IsSet Then
serializer.Serialize(writer, value)
Else
serializer.Serialize(writer, Nothing)
End If
End Sub
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType = GetType(WorkWeek)
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Throw New NotImplementedException()
End Function
End Class
为WorkDay添加一个便利属性,如下所示:
Public Class WorkDay 'working day
<JsonProperty("start")>
Public Property starttime As String
<JsonProperty("end")>
Public Property endtime As String
Public Property breaks As New List(Of Break)
Friend ReadOnly Property IsSet As Boolean
Get
Return Not (String.IsNullOrEmpty(starttime) AndAlso
String.IsNullOrEmpty(endtime))
End Get
End property
End Class
您可以在序列化对象时指定转换器:
Dim s = JsonConvert.SerializeObject(x, new WorkWeekConverter())
这给了你:
{&#34;星期一&#34;:{&#34;开始&#34;:&#34;今天&#34;,&#34;结束&#34;:&#34;今天,晚上&#34 ;,&#34;场所&#34;:[]},&#34;星期二&#34;:空,&#34;星期三&#34;:空,&#34;周四&#34;:空,&# 34;周五&#34;:空,&#34;星期六&#34;:空,&#34;周日&#34;:空}
即如果x等于:
Dim x As New WorkWeek
x.monday.starttime = "today"
x.monday.endtime="today, evening"
答案 1 :(得分:1)
获得所需结果的一种方法是摆脱WorkWeek
类并在其位置使用字典。在另一个问题中,您将数据反序列化为一个,无论如何都要将其用作集合。因此:
' or use a string array to enforce the name and casing
Public Enum WkDays
sunday
monday
tuesday
wednesday
thursday
friday
saturday
End Enum
Dim wrkwk As New Dictionary(Of WkDays, WorkDay)
For Each v As WkDays In [Enum].GetValues(GetType(WkDays))
wrkwk.Add(v, New WorkDay)
Next
使用新的空WorkDay对象初始化集合非常重要,这样您就不必在任何地方检查Nothing。为此,您可以使用一个函数来确保它始终发生。此版本使用字符串数组作为键:
Private Function GetNewWorkWeek() As Dictionary(Of String, WorkDay)
Dim days = {"sunday", "monday", "tuesday", "wednesday",
"thursday", "friday", "saturday"}
Dim wrkwk As New Dictionary(Of String, WorkDay)
' add new, empty WorkDay objects
For Each d As String In days
wrkwk.Add(d, New WorkDay)
Next
Return wrkwk
End Function
' usage:
Dim wrkwk = GetNewWorkWeek()
由于存在/指定5或7天可能是最正常的,通过使用空WorkDay
个对象初始化它,您不必在代码中散布If x IsNot Nothing
。而不是必须检查和创建工作日,从词典中获取一个工作日:
' get a workday to work with
Dim wd As WorkDay = wrkwk(WkDays.sunday)
wd.starttime = "08:00"
wd.endtime = "17:30"
Dim b As New Break
b.starttime = "10:05"
b.endtime = "10:20"
wd.breaks.Add(b)
' etc
对于假期,您可以删除该工作日,但它只是不在列表中,使其显示为“null”使其成为Nothing
:
wrkwk(WkDays.tuesday) = Nothing
Dim jstr = JsonConvert.SerializeObject(wrkwk)
结果:
{
"sunday": {
"start": "08:00",
"end": "17:30",
"breaks": [{
"start": "10:05",
"end": "10:20"
}, {
"start": "14:05",
"end": "14:20"
}]
},
"monday": {
...
},
"tuesday": null,
"wednesday": {
当然,它会反序列化回字典就好了。有几种方法可以解决它并使用它。客户转换器也是一个好主意。
在这种情况下,您至少应该考虑删除tuesday
对象。测试这个更容易:
If myWorkWeek.ContainsKey(WkDays.tusday) Then...
而不是在任何地方(即使你每年有364天的数据,因为ONE可能为null,所有代码都必须考虑到这一点!):
If myWorkWeek(n) IsNot Nothing Then...
答案 2 :(得分:0)
要为生成的JSON设置null
tuesday
,您需要WorkWeek
上的相应对象为Nothing
- 但是在您的构造函数中,你明确地创建它。您希望按需创建,或在适当时清除它。