我知道有一些我想念的事实。我的整个项目有点复制和粘贴各种“如何...”,我对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<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 time-taken 2016-02-08 15:49:52 :: 1 POST / blz / AddNote - 80 - :: 1 - - 500 0 0 2937
答案 0 :(得分:4)
好的,所以有几件事你需要改变才能使它工作:
将无参数构造函数添加到Note中,因为反序列化需要它:
public Note()
{
}
摆脱&#34;静态&#34;在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;组; }
如果您只想要一个对象,则不要发送JSON数组,它不会反序列化。你期待单个对象,而不是数组,所以不要发送数组。
你有类型为bool,但你发送字符串&#34; 1&#34;,这不会像你预期的那样反序列化为真值。发送true / false(不是&#34; true&#34; /&#34; false&#34;)或将Type类型更改为string。
摆脱那个私人物品字段,你不需要它:
私人注意事项;
摆脱那里的那些构造函数
public Note(string json)
公共注释(注释项目)
不仅因为它们毫无意义而且无法工作,您也不需要它们,因为JSON解串器会为您填充字段。
修改强> 例如,你说它没有构建,因为不再有一个带有一个参数的构造函数。当然它没有建立,有这条线
Note notesdata = new Note(item);
但你不需要那条线。这条线背后的想法是什么?你想要一个Note类的实例,但你已经在&#34; item&#34;变量。您无需创建该文件的第二个副本。所以也摆脱这个。
另一个原因是,它为什么不能编译,你可以摆脱那些静态字段,而你仍然可以在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来处理数据库。因此,该部分可能存在一些问题,但我无法对此发表评论。