简体   繁体   English

ServiceStack 请求体

[英]ServiceStack Request Body

I am trying to write my 1st REST service in servicestack and ormlite.我正在尝试在 servicestack 和 ormlite 中编写我的第一个 REST 服务。 It's not going too bad.不会太糟。

I have managed to write the code that displays all records, records based on and ID and delete a record based on an ID.我设法编写了显示所有记录、基于 ID 的记录并删除基于 ID 的记录的代码。

Now I am moving onto adding and editing a record and I am getting confused about how to get the data from the request body of the call.现在我开始添加和编辑记录,我对如何从调用的请求正文中获取数据感到困惑。

I am doing a我正在做一个

POST: http://localhost:7571/equipment/create/123

with the request body of与请求正文

[{"eMCo":"1","equipment":"DP112","location":"Field","manufacturer":"","model":"","modelYr":"2013","vinNumber":"","description":"Trevor","status":"A","attachToEquip":"BR118","licensePlateNo":""}]

But in my service I cannot work out how to access the request body data in this function:但是在我的服务中,我无法弄清楚如何在此函数中访问请求正文数据:

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;
    }

Here is the complete code... If you can point out ANYTHING I am doing wrong please do !这是完整的代码......如果你能指出我做错的任何事情,请做!

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;
    }
}
}

Any help would be greatly appreciated!任何帮助将不胜感激!

Thanks谢谢

UPDATED CODE:更新代码:

ServiceEquipment.cs服务设备.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:应用主机.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();
    }
}

} }

Your problem is to do with the case difference between your JSON data and your DTO.您的问题与 JSON 数据和 DTO 之间的大小写差异有关。 The mapping is case sensitive.映射区分大小写。 The equipment parameter is populated because the case matches, but the rest of the properties don't.填充equipment参数是因为案例匹配,但其余属性不匹配。

You can solve this by adding this line to your AppHost Configuration.您可以通过将此行添加到AppHost配置来解决此问题。

JsConfig.EmitCamelCaseNames = true;

This sets the serializer to map the location in your JSON data to Location in your DTO and the other properties , and handles the conversion back when you serialize.这组串行映射location在你的JSON数据来Location你的DTO和其他属性,当你序列,并处理转换回来。

So you can then access the property on the request parameter, and not through the raw data.因此,您可以访问请求参数上的属性,而不是通过原始数据。


Your service looks OK.您的服务看起来不错。 I can't immediately see any issue with it, I think the issue may then lie with how you are calling the service.我无法立即看到它有任何问题,我认为问题可能在于您如何调用服务。

These methods below will help with debugging the issue.下面的这些方法将有助于调试问题。 I recommend that you try calling the client using this simple HTML page, and see if you get the required fields populated.我建议您尝试使用这个简单的 HTML 页面调用客户端,看看是否填充了必填字段。

Create a file, call it test.html and put it in the bin folder with your ServiceStack service assembly, and navigate to your service path http://localhost:7571/test.html .创建一个文件,将其命名为test.html并将其与 ServiceStack 服务程序集放在bin文件夹中,然后导航到您的服务路径http://localhost:7571/test.html

<!doctype html>
<html>
    <head>
        <title>Test</title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script>
            function send()
            {
                // Send data to the service
                $.ajax({
                    type: "POST",
                    url: "/equipment/create/DP112",
                    contentType: "application/json",
                    data: JSON.stringify({
                        eMCo: "1",
                        equipment: "DP112",
                        location: "Field",
                        manufacturer: "",
                        model: "",
                        modelYr: "2013",
                        vinNumber: "",
                        description: "Trevor",
                        status: "A",
                        attachToEquip: "BR118",
                        licensePlateNo: ""
                    })
                }).done(function(result){

                });
            }
        </script>
</head>
<body>
    <button onclick="send()">Send Request</button>
</body>
</html>

This html file should provide a properly formed request.此 html 文件应提供格式正确的请求。

Also consider adding the Request Logger, by adding this line to your AppHost Configure.还可以考虑通过将此行添加到您的 AppHost 配置来添加请求记录器。 Then go to http://localhost:7571/requestlogs .然后转到http://localhost:7571/requestlogs See here for more information.请参阅此处了解更多信息。

Plugins.Add(new RequestLogsFeature());

Request ContentType:请求内容类型:

If the correct content type is not set on the client request then ServiceStack will not populate the values into the request.如果客户端请求中未设置正确的内容类型,则 ServiceStack 不会将值填充到请求中。 Setting the contentType on the request to application/json works.将请求的contentType设置为application/json有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM