Reputation: 994
I have a table
abstract public class TableDefault
{
[Index(Unique = true)]
[Alias("rec_version")]
[Default(typeof(int), "nextval('rec_version_seq')")]
[Required]
public int Rec_Version { get; set; }
[Index(Unique = true)]
[Alias("rec_id")]
[Default(typeof(int), "nextval('rec_id_seq')")]
[Required]
public int Rec_Id { get; set; }
[Default(typeof(DateTime), "now()")]
[Alias("rec_created")]
[Required]
public DateTime Rec_Create { get; set; }
[References(typeof(UserAuth))]
[Alias("rec_created_id")]
[Required]
public int Rec_Created_Id { get; set; }
[Default(typeof(string), "'1'")]
[Required]
[StringLength(1)]
public string Status { get; set; }
[Default(typeof(DateTime), "now()")]
[Alias("rec_modified")]
[Required]
public DateTime Rec_Modified { get; set; }
[References(typeof(UserAuth))]
[Alias("rec_modified_id")]
[Required]
public int Rec_Modified_Id { get; set; }
}
And
[Alias("dmdvcs")]
public class DmDvcs : TableDefault
{
[Alias("ma_dvcs")]
[PrimaryKey]
[Default(typeof(string), "''")]
public string Ma_Dvcs { get; set; }
[Required]
[Default(typeof(string), "''")]
[Alias("ten_dvcs")]
public string Ten_Dvcs { get; set; }
}
Here is my ServiceStack
[Route("/dmdvcs/{Rec_Id}/{Rec_Version}/ten_dvcs/{Ten_Dvcs}", "PUT")]
public class Update_DmDvcs_Ten : IReturn<DmDvcs>
{
public string Ten_Dvcs { get; set; }
public int Rec_Version { get; set; }
public int Rec_Id { get; set; }
}
public object Put(Update_DmDvcs_Ten request)
{
if (string.IsNullOrEmpty(request.Ten_Dvcs))
throw new ArgumentNullException("Ten_Dvcs");
if (request.Rec_Id == null)
throw new ArgumentNullException("Rec_Id");
if (request.Rec_Version == null)
throw new ArgumentNullException("Rec_Version");
var eXistsRow = Db.Select<DmDvcs>(q => q.Rec_Id == request.Rec_Id);
if (eXistsRow.Count == 0)
throw HttpError.NotFound("Row {0} does not exist".Fmt(request.Rec_Id));
else if (eXistsRow.First().Rec_Version != request.Rec_Version)
throw HttpError.NotFound("Row {0} need update".Fmt(request.Rec_Id));
IAuthSession session = this.GetSession();
int rec_version_seq = Db.GetScalar<int>("SELECT nextval('rec_version_seq')");
DmDvcs updateRow = new DmDvcs
{
Ten_Dvcs = request.Ten_Dvcs,
Rec_Modified = DateTime.Now,
Rec_Modified_Id = session.UserAuthId.ToInt(0),
Rec_Version = rec_version_seq
};
Db.UpdateOnly(updateRow,
ev => ev.Update(c => new { c.Ten_Dvcs, c.Rec_Modified, c.Rec_Modified_Id, c.Rec_Version })
.Where(p => p.Rec_Id == request.Rec_Id));
var newRec = Db.Select<DmDvcs>(p => p.Rec_Id == request.Rec_Id);
return newRec;
}
On REST console :
http://localhost:9998/dmdvcs/8479/8498/ten_dvcs/TestName
return
[{
"Ma_Dvcs": "DEMO.000",
"Ten_Dvcs": "TestName",
"Rec_Version": 8499,
"Rec_Id": 8479,
"Rec_Create": "2013-07-01T13:35:02.5430000",
"Rec_Created_Id": 1,
"Status": "1",
"Rec_Modified": "2013-07-01T13:42:37.6910000",
"Rec_Modified_Id": 1
}]
But on Visual Studio Test
[TestMethod]
public void DmDvcs_update_dvcs_ten()
{
try
{
var client = (ServiceClientBase)GetClientWithUserPassword();
client.AlwaysSendBasicAuthHeader = true;
DmDvcs getRow = client.Get(new Get_All_Dvcs())[0];
DmDvcs response = client.Put(new Update_DmDvcs_Ten { Rec_Version = getRow.Rec_Version, Rec_Id = getRow.Rec_Id, Ten_Dvcs = getRow.Ten_Dvcs });
Assert.AreNotEqual(response, null);
}
catch (WebServiceException webEx)
{
Assert.Fail(webEx.Message);
}
}
it has error
System.Runtime.Serialization.SerializationException was unhandled by user code
HResult=-2146233076
Message=Type definitions should start with a '{', expecting serialized type 'DmDvcs', got string starting with: [{"Ma_Dvcs":"DEMO.HNO","Ten_Dvcs":"34234","Rec_Ver
Source=ServiceStack.Text
StackTrace:
at ServiceStack.Text.Common.DeserializeTypeRefJson.StringToType(Type type, String strType, EmptyCtorDelegate ctorFn, Dictionary`2 typeAccessorMap)
at ServiceStack.Text.Common.DeserializeType`1.<>c__DisplayClass3.<GetParseMethod>b__1(String value)
at ServiceStack.Text.Json.JsonReader`1.Parse(String value)
at ServiceStack.Text.JsonSerializer.DeserializeFromString[T](String value)
at ServiceStack.Text.JsonSerializer.DeserializeFromStream[T](Stream stream)
at ServiceStack.ServiceModel.Serialization.JsonDataContractDeserializer.DeserializeFromStream[T](Stream stream)
at ServiceStack.ServiceClient.Web.JsonServiceClient.DeserializeFromStream[T](Stream stream)
at ServiceStack.ServiceClient.Web.ServiceClientBase.HandleResponse[TResponse](WebResponse webResponse)
at ServiceStack.ServiceClient.Web.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request)
at ServiceStack.ServiceClient.Web.ServiceClientBase.Put[TResponse](IReturn`1 request)
at TSNext.Service.Tests.DmDvcsTests.DmDvcs_update_dvcs_ten() in z:\future13\api\3SNext.Service.Tests\DmDvcsTests.cs:line 170
InnerException:
What happen with my ServiceStack. I am using ServiceStack 3.9.54 and PostgreSQL 9.2
Upvotes: 3
Views: 6360
Reputation: 143319
This error is usually an indication that the JSON payload doesn't match the shape of the models you're trying to deserialize into.
In your Request DTO it says this service will return the DmDvcs
POCO:
public class Update_DmDvcs_Ten : IReturn<DmDvcs> { ... }
But you're returning a List<DmDvcs>
instead:
public object Put(Update_DmDvcs_Ten request)
{
...
var newRec = Db.Select<DmDvcs>(p => p.Rec_Id == request.Rec_Id);
return newRec;
}
Which is why your JSON looks like:
[{ "Ma_Dvcs": "DEMO.000",.. }]
And not the single DmDvcs object it expects, i.e:
{"Ma_Dvcs": "DEMO.000",..}
To prevent this in future I recommend specifying the return type so it matches your IReturn<T>
response marker and will display a type error if you're not returning what it expects.
public List<DmDvcs> Put(Update_DmDvcs_Ten request) { ... }
Upvotes: 4