我有一个servicestack服务,它接受一个如下所示的DTO:
[Route("/appointment/{id}", Verbs = "POST")]
public class UpdateAppointment
{
public Guid Id { get; set; }
public DateTime StartTime { get; set; }
public int Duration { get; set; }
public string Description { get; set; }
public Guid? MemberId { get; set; }
}
如何检查ClientId值是否由客户端设置,因为“null”是有效值。通常,如果NULL不是有效值,我可以使用PopulateWithNonDefaultValues()方法。
所以结果应该是如果我没有在HTTP POST有效负载中指定MemberId,我希望服务器不更新该值。
我希望这是有道理的。
答案 0 :(得分:2)
如果您认为客户端在调用UpdateAppointment
服务时始终提供所有值,则通常不会出现此问题。所以我强烈建议您考虑每个属性是客户端提供的“有效”值并更新所有字段。
如果只想更新部分属性列表,请创建单独的服务。
如果我真的需要检查客户端是否提供了值,您可以在Request DTO构造函数中指定不同的值,例如:
public class UpdateAppointment
{
public UpdateAppointment()
{
MemberId = Guid.Empty;
}
//...
}
其中非Guid.Empty
值表示它已由客户填充。
或者您也可以使用计算出的属性:
public class UpdateAppointment
{
[IgnoreDataMember]
public bool HasMemberId { get; set; }
Guid? memberId;
public Guid? MemberId
{
get { return memberId; }
set
{
memberId = value;
HasMemberId = true;
}
}
}
更脆弱的替代方法是使用全局请求过滤器缓冲请求:
appHost.PreRequestFilters.Add((httpReq, httpRes) => {
httpReq.UseBufferedStream = true;
});
其中会保留一份请求流副本,您可以通过以下方式获取服务副本:
var jsonBody = base.Request.GetRawBody();
var hasMemberId = jsonBody.ToLower().Contains("memberid");
虽然注意这是依赖于序列化程序的,即不能使用像ProtoBuf或MsgPack这样的二进制序列化程序。
答案 1 :(得分:1)
如果不允许空值,为什么MemberId
可以为空?
只需将其定义更改为:
public Guid MemberId { get; set; }
答案 2 :(得分:0)
您是否尝试先加载值,然后在更新前对其进行编辑?
我的意思是:
[HttpPost]
public ActionResult Update(UpdateAppointment UAForm){
UpdateAppointment ua = new UpdateAppointmentBll().Find(UAForm.Id);
ua.StartTime = UAForm.StartTime;
//so no...
if(UAForm.MemberId != null)
ua.MemberId = UAForm.MemberId;
new UpdateAppointmentBll().Save(ua);
return View();
}