【问题标题】:Issue with RESTful webservice +JSON+SQL stored procedure projectRESTful webservice +JSON+SQL 存储过程项目的问题
【发布时间】:2016-02-08 14:52:14
【问题描述】:

我知道我想念一些东西。我的整个项目有点像各种“如何...”的复制和粘贴,我对 C# 的了解充其量只是基本的,我需要让它工作,因为我们的标准 Web 服务软件仅在发送时是 RESTful 的。

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

要求:可以在 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:内部服务器错误,参数项的值不能为空

这是 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 类中删除私有 Note 2. 将 Node 中的公共静态属性更新为 public 3. 在 Add 方法中使用 item 而不是 Node 还要检查这本书 asp.net/web-api/books 如果你有一些截止日期,这本书可以帮助 ASP.NET Web API 2 食谱
  • @VadimSentyaev Private Note 是来自 VB 的建议 - 删除会导致错误“'Note' 不包含'item' 的定义,并且没有扩展方法'item' 接受'Note' 类型的第一个参数可以找到(您是否缺少 using 指令或程序集引用?) NA”删除静态属性会导致在存储过程调用中用作参数的变量出现错误“非静态字段、方法或属性需要对象引用...”。
  • 只是一个猜测:您是否将 json 从不同的主机发布到您的服务?可能是跨源json问题吗? asp.net/web-api/overview/security/…
  • @Lorin 实际上,我从位于同一台机器、服务器(Windows 和 IIS)上的不同 Web 服务发布,使用与其他相同的设置,目前可以正常工作。因此,除非有一些奇怪的原因导致 IIS 无法处理两个 Web 服务,否则我在 POST 端看不到问题。如果有的话,罪魁祸首应该是作为上述项目一部分的服务。

标签: c# json web-services rest sql-server-2012


【解决方案1】:

好的,因此您需要更改几项才能使其正常工作:

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

    public Note()
    {
    }
    
  2. 去掉 Note 字段中的“静态”:

    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. 如果您只需要 1 个对象,请不要发送 JSON 数组,它不会反序列化。您期待单个对象,而不是数组,所以不要发送数组。

  4. 您的类型为 bool,但您发送字符串“1”,这不会像您预期的那样反序列化为真值。要么发送真/假(不是“真”/“假”),要么将类型的类型更改为字符串。

  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 来处理 DB。所以这部分可能存在一些问题,但我不能对此发表评论。

【讨论】:

  • 感谢指点。但是当我从笔记的字段中删除静态时,它们在 addNote 方法中不再可用。与控制器中的 new (Note.item) 相同 - 添加无参数构造函数后出现错误 Note.Note() 不包含采用 1 个参数的构造函数。所以解决方案没有建立。最后:是的,json 是一个数组。我可能会在档案中收到不止一张便条。为了简单起见,我只是将其缩减为一个对象。
  • PostNote 操作方法必须准确反映正在发送的内容 - 可以发送数组,但在这种情况下,PostNote 必须接受对象数组(或列表)。我理解您对我建议的其他更改的看法,但我的想法是也基于此更改代码的其他部分。有关更多信息,请参阅我的编辑。
  • 再次感谢。 :) 我的评论反映了我的知识水平 - 最低限度。因此,任何“这条线背后的想法是什么”类型的问题都以“我不知道——它出现在其中一篇“如何”文章中”开头。所以你的编辑现在对我来说至少是一个顿悟。至于数据库返回 - 是的,它是必需的。一方面 - 如果它的工作等同于成功,并携带其他系统(发送便笺的系统)的便笺 ID 来存储它。
  • 好的,所以您希望 Add 方法返回带有从数据库中填写的 ID 的 Note。为此,您只需执行 item.id = newId 即可,而无需从 Add 返回 Note。知道调用是否成功是一件好事。为此,使用 bool 作为返回值,或使用异常。但避免将其结合起来。如果 item 为 null,我可以看到您正在抛出 ArgumentNullException。为什么不总是返回 bool - 并在此处返回 false。或者,如果数据库插入失败,为什么不直接使用 void (即不返回任何内容)并使用异常。在我的风格中,我避免异常,所以我总是在那里使用 bool。
  • 明白,非常感谢。最后一个问题 - 在我的解决方案中,从请求正文中获取的实际 json 是在哪里?我需要将 json 作为一个数组,但我可以请求更改结构,所以如果现在不是,我可以让它反序列化。但我对List&lt;Note&gt; deserializednote= JsonConvert.DeserializeObject&lt;List&lt;Note&gt;&gt;(item); 有疑问(项目不是字符串)。如何克服它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 2012-04-18
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多