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

我知道有一件事我怀念。 我的整个项目有点复制和粘贴各种“如何…”,我对C#的了解至多是基本的,我需要让它工作,因为我们的标准Web服务软件仅在发送时才是RESTful。

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

要求:在WS2012R2上使用IIS的东西,可以通过HTTPPost接受JSON文件,将内容转储到SQL Server表中,并将刚刚创建的行的Id返回给JSON的发送者。 我将不得不在它上面构建以获得发送和接收包含不同数据的多个JSON文件的完整Web服务,所有这些都必须以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 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 INoteRepository.GetAll() { throw new NotImplementedException("getitems"); } } } 

控制器:

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

当尝试将测试json发送到服务时,我得到一个错误:

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

这是发送请求的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-status时间2016-02-08 15:49:52 :: 1 POST / blz / AddNote – 80 – :: 1 – – 500 0 0 2937

好的,所以有几件事你需要改变才能使它工作:

  1. 将无参数构造函数添加到Note中,因为反序列化需要它:

     public Note() { } 
  2. 在Note的字段中删除“static”:

    public static string Client {get; 组; }

    public static int Case {get; 组; }

    public static string Text {get; 组; }

    public static int NoteId {get; 组; }

    public static string R1 {get; 组; }

    public static string R2 {get; 组; }

    public static string S1 {get; 组; }

    public static DateTime Date {get; 组; }

    public static bool Type {get; 组; }

  3. 如果只需要一个对象,则不要发送JSON数组,它不会反序列化。 你期待单个对象,而不是数组,所以不要发送数组。

  4. 你有类型为bool,但是你发送字符串“1”,这不会像你预期的那样反序列化为真值。 发送true / false(不是“true”/“false”)或将Type类型更改为string。

  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方法通常没有理由返回要添加到DB的对象。 所以随时改变这一点

  public Note Add(Note item) 

对此

  public void Add(Note item) 

并且不要退货,你不需要它。

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