RESTful Webservice +JSON+SQL 存储过程项目的问题



我知道我错过了一些东西。我的整个项目在某种程度上是复制和粘贴各种"如何...",我对 C# 的了解充其量是基本的,我需要让它工作,因为我们的标准 Web 服务软件仅在发送时是 RESTful 的。

的主要问题是我偶然发现的所有解决方案实际上都是代码片段,这对我不起作用 - 我的 C# 知识是基本的,所以我不明白它是如何工作的,更不用说对其进行故障排除了。我很确定我什至没有捕获与传入请求一起发布的 JSON。但是OTOH我可能是错的。

要求:在WS2012R2上对 IIS 工作的东西,可以通过 HTTPPost 接受 JSON 文件,将内容转储到 SQL Server 表中,并将刚刚创建的行的 Id 返回给 JSON 的发送方。我将不得不在此基础上构建以获得成熟的 Web 服务,该服务发送和接收包含不同数据的多个 JSON 文件,所有这些都必须在 SQL Server 中结束。

我有什么:

类:

    namespace NA.Models
{
    public class Note
    {
        public Note() { }
        //public Guid id { get; set; }
        public static string Client { get; set; }
        public static int Case { get; set; }
        public static string Text { get; set; }
        public static int NoteId { get; set; }
        public static string R1 { get; set; }
        public static string R2 { get; set; }
        public static string S1 { get; set; }
        public static DateTime Date { get; set; }
        public static bool Type { get; set; }
      }
    }

接口

    namespace NA.Models
{
    interface INoteRepository
    {
        IEnumerable<Note> GetAll();
        void Add(Note item);
    }
}

存储 库:

namespace NA.Models
{
  class NoteDataRepository : INoteRepository
  {
     public void Add(Note item)
     {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }
        else
        {
            String strConnString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
            SqlConnection con = new SqlConnection(strConnString);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "BL_IntegrationInsertNote";
            cmd.Parameters.Add("@Client", SqlDbType.VarChar).Value = item.Client.Trim();
            cmd.Parameters.Add("@Case", SqlDbType.VarChar).Value = item.case;
            cmd.Parameters.Add("@Text", SqlDbType.VarChar).Value = item.Text.Trim();
            cmd.Parameters.Add("@When", SqlDbType.DateTime).Value = item.Date;
            cmd.Parameters.Add("@Ext", SqlDbType.Bit).Value = item.Type;
            cmd.Parameters.Add("@return", SqlDbType.Int).Direction = ParameterDirection.Output;
            cmd.Connection = con;
            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                string id = cmd.Parameters["@return"].Value.ToString();
                string lblMessage = null;
                lblMessage = "Record inserted successfully. ID = " + id;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
                con.Dispose();
            }
        }    
        return item;
    }
    IEnumerable<Note> INoteRepository.GetAll()
    {
        throw new NotImplementedException("getitems");
    }
}
}

控制器:

namespace NA.Controllers
{
   public class NC : ApiController
   {
      [Route("AddNote")]
      [HttpPost]
    public HttpResponseMessage PostNote(List<Note> item)
    {
        //NoteJson deserializednote = JsonConvert.DeserializeObject<NoteJson>(item);
        //Note notesdata = new Note(item);
        //foreach (deserializednote   
        NotesAccept.Models.INoteRepository Repository = new NotesAccept.Models.NoteDataRepository();
        item = Repository.Add(item);
        var response = Request.CreateResponse < NotesAccept.Models.Note>(HttpStatusCode.Created, item);
        return response;
    }
   }
}

尝试将测试 json 发送到服务时,我收到一个错误作为回报:

500:内部服务器错误,参数项的值不能为 null

这是发送的请求 posttestserver.com 转储:

Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING = 
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 56926
REMOTE_ADDR = ip
HTTP_CONNECTION = close
HTTP_CACHE_CONTROL = max-age=259200
HTTP_X_FORWARDED_FOR = 172.16.3.87
HTTP_VIA = 1.1 koenig.local (squid/3.3.13)
HTTP_EXPECT = 100-continue
CONTENT_LENGTH = 153
HTTP_HOST = posttestserver.com
HTTP_ACCEPT = application/json
CONTENT_TYPE = application/json
UNIQUE_ID = Vri0cUBaMGUAABvGeesAAAAL
REQUEST_TIME_FLOAT = 1454945393.4611
REQUEST_TIME = 1454945393
No Post Params.
== Begin post body ==
[{
    "Client": "Client1",
    "Case": 1,
    "Text": "Text",
    "NoteId": 2,
    "R1": "R1",
    "R2": "R2",
    "S1": "S1",
    "Date": "2015-10-26T09:06:46",
    "Type":"1"
}]
== End post body ==
Upload contains PUT data:
[{
    "Client": "Client1",
    "Case": 1,
    "Text": "Text",
    "NoteId": 2,
    "R1": "R1",
    "R2": "R2",
    "S1": "S1",
    "Date": "2015-10-26T09:06:46",
    "Type":"1"
}]

上面的转储来自 POST 请求,该请求与我发送到我的 Web 服务的请求相同,但 URL 除外。所以可以视为实际请求。下面是一个 IIS 日志:

字段: 日期时间 s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent( cs(Referer( sc-status sc-substatus sc-win32-状态 时间已用 2016-02-08 15:49:52 ::1 发布/blz/添加说明 - 80 - ::1 - - 500 0 0 2937

好的,所以你需要改变几件事才能使其正常工作:

  1. 将无参数构造函数添加到 Note,因为它是反序列化所必需的:

    public Note()
    {
    }
    
  2. 摆脱Note字段中的"静态":

    公共静态字符串客户端 { get; set; }

    public static int case { get; set; }

    公共静态字符串文本 { get; set; }

    public static int NoteId { get; set; }

    公共静态字符串 R1 { get; set; }

    公共静态字符串 R2 { get; set; }

    公共静态字符串 S1 { get; set; }

    公共静态日期时间日期 { get; set; }

    公共静态布尔类型 { get; set; }

  3. 如果您只需要 1 个对象,请不要发送 JSON 数组,它不会反序列化。您期望的是单个对象,而不是数组,因此不要发送数组。

  4. 您将 Type 作为布尔值,但您正在发送字符串"1",这不会像您预期的那样反序列化为 true 值。发送真/假(不是"真"/"假"(或将类型更改为字符串。

  5. 删除该私有项目字段,您不需要它:

    私人笔记项目;

  6. 摆脱你在那里的那些构造函数

    公共注释(字符串 json(

    公共注释(注释项(

    不仅它们没有意义并且不起作用,您不需要它们,因为 JSON 反序列化程序会为您填充字段。

编辑:例如,你说它不生成,因为不再有一个参数的构造函数。当然不建,有这条线

Note notesdata = new Note(item);

但你不需要那条线。这条线背后的想法是什么?你想要一个 Note 类的实例,但你已经在"item"变量中有了它。您不需要创建该副本的第二个副本。所以也摆脱这个。

它无法编译的另一个原因是你摆脱了这些静态字段,而你的 Add 方法中仍然有这个:

        cmd.Parameters.Add("@Text", SqlDbType.VarChar).Value = Note.Text.Trim();
        cmd.Parameters.Add("@When", SqlDbType.DateTime).Value = Note.Date;

我很确定你不希望这样。相反,您希望使用发送给您的对象的实例:

        cmd.Parameters.Add("@Text", SqlDbType.VarChar).Value = item.Text.Trim();
        cmd.Parameters.Add("@When", SqlDbType.DateTime).Value = item.Date;

另一件事是,通常没有理由为什么 Add 方法返回要添加到数据库的对象。所以请随意更改此内容

   public Note Add(Note item)

对此

   public void Add(Note item)

并且不要返回任何东西,你不需要它。

我不是SqlConnection及其周围事物的专家,因此我不对此发表评论。我在项目中使用 EF 来处理数据库。所以这部分可能存在一些问题,但我不能对此发表评论。

最新更新