【发布时间】:2014-01-12 15:58:12
【问题描述】:
我正在尝试在 servicestack 和 ormlite 中编写我的第一个 REST 服务。情况不会太糟。
我已经编写了代码来显示所有记录、基于 ID 的记录并删除基于 ID 的记录。
现在我开始添加和编辑记录,我对如何从调用的请求正文中获取数据感到困惑。
我正在做一个
POST: http://localhost:7571/equipment/create/123
请求正文为
[{"eMCo":"1","equipment":"DP112","location":"Field","manufacturer":"","model":"","modelYr":"2013","vinNumber":"","description":"Trevor","status":"A","attachToEquip":"BR118","licensePlateNo":""}]
但在我的服务中,我无法弄清楚如何在此函数中访问请求正文数据:
public object Post(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
//base.Request.FormData[""]
db.Insert(request);
}
return null;
}
这是完整的代码...如果您能指出我做错的任何事情,请做!
using ServiceStack;
using ServiceStack.OrmLite;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
namespace ViewPoint
{
[Api("Enables viewiing, creation, updating and deletion of equipment from the EMEM table.")]
[Route("/equipment", "GET")]
[Route("/equipment/detail/{equipment}", "GET")]
[Route("/equipment/delete/{equipment}", "DELETE")]
[Route("/equipment/update/{equipment}", "PATCH")]
[Route("/equipment/create/{equipment}", "POST")]
public class EMEMTrev
{
public string eMCo { get; set; }
public string equipment { get; set; }
public string Location { get; set; }
public string Manufacturer { get; set; }
public string Model { get; set; }
public string ModelYr { get; set; }
public string VINNumber { get; set; }
public string Description { get; set; }
public string Status { get; set; }
public string AttachToEquip { get; set; }
public string LicensePlateNo { get; set; }
}
public class EMEMTrevResponse
{
public string eMCo { get; set; }
public string equipment { get; set; }
public string Location { get; set; }
public string Manufacturer { get; set; }
public string Model { get; set; }
public string ModelYr { get; set; }
public string VINNumber { get; set; }
public string Description { get; set; }
public string Status { get; set; }
public string AttachToEquip { get; set; }
public string LicensePlateNo { get; set; }
public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized
}
public class EquipmentService : Service
{
public object Get(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
if (request.equipment == null)
{
List<EMEMTrev> results = db.Select<EMEMTrev>();
return results;
}
else
{
List<EMEMTrev> results = db.Select<EMEMTrev>(p => p.Where(ev => ev.equipment == request.equipment));
return results;
}
}
}
public object Delete(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
db.Delete<EMEMTrev>(p => p.Where(ev => ev.equipment == request.equipment));
}
return null;
}
public object Post(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
//base.Request.FormData[""]
db.Insert(request);
}
return null;
}
public object Patch(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
db.Update(request);
}
return null;
}
}
}
任何帮助将不胜感激!
谢谢
更新代码:
ServiceEquipment.cs
using ServiceStack;
using ServiceStack.OrmLite;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Web;
namespace ViewPoint
{
[Api("Enables viewiing, creation, updating and deletion of equipment from the EMEM table. Use a POST to create an EMEM or a PUT to update one.")]
[Route("/equipment", "GET,POST,PUT")]
[Route("/equipment/{equipment}", "GET,DELETE")]
public class EMEMTrev
{
public string eMCo { get; set; }
public string equipment { get; set; }
public string location { get; set; }
public string manufacturer { get; set; }
public string model { get; set; }
public string modelYr { get; set; }
public string vinNumber { get; set; }
public string description { get; set; }
public string status { get; set; }
public string attachToEquip { get; set; }
public string licensePlateNo { get; set; }
}
public class EMEMTrevResponse
{
public EMEMTrev emem { get; set; }
public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized
}
public class EquipmentService : Service
{
public object Get(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
if (request == null)
{
List<EMEMTrev> results = db.Select<EMEMTrev>();
return results;
}
else
{
List<EMEMTrev> results = db.Select<EMEMTrev>(p => p.Where(ev => ev.equipment == request.equipment));
return results;
}
}
}
public object Delete(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
db.Delete<EMEMTrev>(p => p.Where(ev => ev.equipment == request.equipment));
}
return new HttpResult
{
StatusCode = HttpStatusCode.NoContent,
Headers =
{
{HttpHeaders.Location, this.Request.AbsoluteUri.CombineWith(request.equipment)}
}
};
}
public object Post(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
db.Insert(request);
}
return new HttpResult()
{
StatusCode = HttpStatusCode.Created,
Headers =
{
{HttpHeaders.Location, base.Request.AbsoluteUri.CombineWith(request.equipment)}
}
};
}
public object Put(EMEMTrev request)
{
var dbFactory = new OrmLiteConnectionFactory("Data Source=(local);Initial Catalog=Kent;Integrated Security=True", SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
db.Update(request);
}
return new HttpResult
{
StatusCode = HttpStatusCode.NoContent,
Headers =
{
{HttpHeaders.Location, base.Request.AbsoluteUri.CombineWith(request.equipment)}
}
};
}
}
}
AppHost.cs:
using System.Configuration;
using ServiceStack;
using ServiceStack.Auth;
using ServiceStack.Configuration;
using ServiceStack.Data;
using ServiceStack.OrmLite;
[assembly: WebActivator.PreApplicationStartMethod(typeof(ViewPoint.App_Start.AppHost), "Start")]
/**
* Entire ServiceStack Starter Template configured with a 'Hello' Web Service and a 'Todo' Rest Service.
*
* Auto-Generated Metadata API page at: /metadata
* See other complete web service examples at: https://github.com/ServiceStack/ServiceStack.Examples
*/
namespace ViewPoint.App_Start
{
public class AppHost : AppHostBase
{
public AppHost() //Tell ServiceStack the name and where to find your web services
: base("StarterTemplate ASP.NET Host", typeof(EquipmentService).Assembly) { }
public override void Configure(Funq.Container container)
{
//Set JSON web services to return idiomatic JSON camelCase properties
ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
//Configure User Defined REST Paths
//Routes
// .Add<Hello>("/hello")
// .Add<Hello>("/hello/{Name*}");
//Uncomment to change the default ServiceStack configuration
//SetConfig(new HostConfig {
//});
//Enable Authentication
//ConfigureAuth(container);
//Register all your dependencies
//container.Register(new TodoRepository());
}
/* Example ServiceStack Authentication and CustomUserSession */
private void ConfigureAuth(Funq.Container container)
{
var appSettings = new AppSettings();
//Default route: /auth/{provider}
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CredentialsAuthProvider(appSettings),
new FacebookAuthProvider(appSettings),
new TwitterAuthProvider(appSettings),
new BasicAuthProvider(appSettings),
}));
//Default route: /register
Plugins.Add(new RegistrationFeature());
//Requires ConnectionString configured in Web.Config
var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;
container.Register<IDbConnectionFactory>(c =>
new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider));
container.Register<IUserAuthRepository>(c =>
new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));
container.Resolve<IUserAuthRepository>().InitSchema();
}
public static void Start()
{
new AppHost().Init();
}
}
}
【问题讨论】:
-
我注意到的第一件事是您的 JSON 样本是数组中的一个对象:
[{...}],但您的请求 DTO 是一个普通对象。如果您删除这些方括号,使您的 JSON 看起来像{...},您的应用程序会表现得更好吗? -
@esker 谢谢 - 试过了。没有变化:(
-
您能否更详细地解释一下具体的问题是什么?
Post请求中的request对象是否为空,即使从请求 JSON 中删除了方括号?或者request对象中是否有个别属性意外为空?还是在您发送请求时甚至没有调用Post方法?等 -
@TrevorDaniel 我很困惑你为什么要访问原始身体数据。特别是如果您发送的原始数据是 JSON,并且会自动反序列化为您的方法的请求参数。如果您发送有效的 JSON,那么您的数据应该可以使用
request.Description或request.ModelYr等访问。您使用什么客户端发送请求? -
@Scott 嗨,你可能已经发现了我的错误。当我打电话给 POST:localhost:7571/equipment/create/123 我可以看到“123”但我看不到“描述”,例如它是空的,这就是为什么我认为我必须做一些事情来阅读请求正文?客户端? - 我一直在尝试用 Fiddler 调用函数
标签: c# servicestack ormlite-servicestack